Is there a way to allow builder type inference with a default value if the type isn't inferable? For example,
Copy code
interface Builder<T> {
fun initialValue(value: T)
fun otherMethodsThatWithoutT()
}
fun <T> build(block: Builder<T>.()->Unit) =
BuilderImpl<T>().apply(block)
val buildWithType = build { initialValue(0.0) } // T = Double
bal buildWithouType = build { } // Default T to Unit
m
Michael de Kaste
11/13/2023, 1:06 PM
default values for generic types isn't available, so your best bet would be to create a second function or value.
best bet would be:
Copy code
val build = BuilderImpl<Unit>()
fun build() = BuilderImpl<Unit>()
d
Daniel Pitts
11/14/2023, 2:44 AM
I've tried having a second function, but then overload doesn't work.
Copy code
fun <S> sketch(build: SketchBuilder<S>.() -> Unit) {
SketchBuilderImpl<S>().apply(build)
}
fun sketch(build: SketchBuilder<Unit>.() -> Unit) {
SketchBuilderImpl<Unit>().apply(build)
}
fun makeSketches() {
sketch {
// `this` is SketchBuilder<Unit>
}
sketch {
initialState("") // compiler error: type mismatch, expected Unit, got String
}
sketch<String> {
// `this` is SketchBuilder<String>, but annoying to have to put the type here
initialState("")
}
}
Daniel Pitts
11/14/2023, 2:46 AM
So, the user of my DSL will have to explicitly state its typeless, or explicitly state the type.
Daniel Pitts
11/14/2023, 2:46 AM
I think this is the next best approach:
Copy code
fun <S> sketch(build: SketchBuilder<S>.() -> Unit) {
SketchBuilderImpl<S>().apply(build)
}
val SketchBuilder<Unit>.stateless get() = Unit
fun makeSketches() {
sketch {
stateless
// `this` is SketchBuilder<Unit>
}
sketch {
initialState("")
// `this` is SketchBuilder<String>
}
}