Andy Gibel
02/05/2021, 6:06 PMinterface A and one of interface B
is there a way to write a generic convert function using inline reified that will convert A to B if and only if a conversion function fun(a) : B exists?Marc Knaup
02/05/2021, 6:08 PMMarc Knaup
02/05/2021, 6:09 PMinterface A: ConvertibleToB but that’s not very generic.Marc Knaup
02/05/2021, 6:10 PMConvertibleTo<T> would be an option, but also has various downsidesNir
02/05/2021, 6:11 PMAndy Gibel
02/05/2021, 6:12 PMConvertableTo<T> seems like a reasonable approach... This would in turn just replace a build in version of "check if this function exists" right?Marc Knaup
02/05/2021, 6:13 PMA.
Also, you can only convert to a single type.
You cannot do A: ConvertableTo<B>, ConvertableTo<C>Nir
02/05/2021, 6:14 PMNir
02/05/2021, 6:14 PMNir
02/05/2021, 6:15 PMMarc Knaup
02/05/2021, 6:17 PMKClass-based conversion registry.
And then
fun aToB(a: A): B {…}
…
conversionRegistry.add(::aToB)
…
val b = conversionRegistry.convertOrNull<B>(a)
But that only checks types at runtime.Nir
02/05/2021, 6:18 PMNir
02/05/2021, 6:19 PMfun <A, B> do_work(someParam: Param, converter: (A) -> B) { ... }Marc Knaup
02/05/2021, 6:19 PMNir
02/05/2021, 6:19 PMdo_work "just knowing" how to convert an A to B based on some assumed trait.Nir
02/05/2021, 6:19 PMNir
02/05/2021, 6:19 PMAndy Gibel
02/05/2021, 6:22 PMpostInput(input : InputType)
output() : Observable<OutputType>
I'd like to be able to tie these widgets together in the fashion:
widget1.output().subscribe{ widget2.postInput(it.toWidget2Input)
}
However I'd like to have this abstracted so that caller code could connect widgets with something like a DSL
val widgetConnections = connect {
widget1 to widget2,
widget1 to widget3,
widget2 to widget4,
}
but this would require that I have some generic way to convert between inputs and outputsMarc Knaup
02/05/2021, 6:24 PMMarc Knaup
02/05/2021, 6:25 PMAndy Gibel
02/05/2021, 6:25 PMNir
02/05/2021, 6:25 PMNir
02/05/2021, 6:26 PMval widgetConnections = connect {
widget1 to { foo(it) } to widget2,
widget1 to widget3,
widget2 to widget4,
}Andy Gibel
02/05/2021, 6:26 PMclass ConverterToCX() { invoke()...}Nir
02/05/2021, 6:27 PMto to make this work so you may want to use a different infix function at that pointNir
02/05/2021, 6:27 PMNir
02/05/2021, 6:27 PMMarc Knaup
02/05/2021, 6:28 PMinfix fun [ConnectScope, Widget1].to(output: Widget2) {
// register your conversion function
}
Basically each conversion function is an extension function for your DSL scope. But doesn’t work with today’s Kotlin.
This approach needs multiple receivers.Nir
02/05/2021, 6:28 PMNir
02/05/2021, 6:29 PMAndy Gibel
02/05/2021, 6:30 PMNir
02/05/2021, 6:30 PMobject Connector {
fun register() // okay register converters here
}
fun connect(user_dsl: Connector.() -> Unit) { ... }Marc Knaup
02/05/2021, 6:31 PMInput or Output widget type then you can use the ConvertibleTo<…> approach, but with different variants.
A: ConvertibleTo1<B>
A: ConvertibleTo2<B,C>
A: ConvertibleTo3<B,C,D>
// etc.
or
A: ConvertibleTo1<B>, ConvertibleTo2<C>, ConvertibleTo3<D>
// etc.Marc Knaup
02/05/2021, 6:31 PMConvertibleTo1<T>, ConvertibleTo2<T,U>, ConvertibleTo3<T,U,V> etc.Andy Gibel
02/05/2021, 6:33 PM