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