Does anyone know why Given an interface like: ```i...
# compiler
c
Does anyone know why Given an interface like:
Copy code
interface SynkAdapter<T : Any> : IDResolver<T>, MapEncoder<T>
An impl like this does not count as the aggregated type (SynkAdapter)
Copy code
class FooSynkAdapter(
    private val fooResolver: IDResolver<Foo> = FooResolver(),
    private val fooMapEncoder: MapEncoder<Foo> = FooMapEncoder()
) : IDResolver<Foo> by fooResolver, MapEncoder<Foo> by fooMapEncoder
You have to do this??
Copy code
class FooSynkAdapter(
    private val fooResolver: IDResolver<Foo> = FooResolver(),
    private val fooMapEncoder: MapEncoder<Foo> = FooMapEncoder()
) : SynkAdapter<Foo>, IDResolver<Foo> by fooResolver, MapEncoder<Foo> by fooMapEncoder
Surely if an interface is just a union of two other interfaces then implementing those interfaces should make it compatible? I’m sure there must be a good reason for having to be explicit?
s
Kotlin just isn’t duck-typed 🤷. To be a thing, you have to actually be the thing.
v
Just that it has the same methods does not mean it should be the same. Imho it is good that you need to be explicit, as Kotlin is not duck-typed.
c
Well I get why duck typing can be a bit too flexible, but in this case it seems to be quite different. Its not simply that my impl contains a function which has a signature which happens to match
I’m explicitly implementing the two interfaces which make up the composite
feels like we could use a new keywork
union interface
s
You want an intersection, not a union
Technically, you can make one, with generics
c
or that yes 😛
s
fun <A, B> doSomethingWith(a: A) where A: IDResolver<B>, A: MapEncoder<B>
It’s not possible to denote the intersection type outside of a generic constraint, though 😞
c
Well I’ll write the extra interface for now 😄, isn’t there work being done on union types? maybe this will extend to intersection types?
s
Yes, the ticket does cover both intersections and unions 😍
v
While I wouldn't expect that it would automagically have the
SnykAdapter
type with that change either 🙂
s
You could get close though, with a type alias:
Copy code
typealias SynkAdapter<T> = IDResolver<T> & MapEncoder<T>
Just that
SynkAdapter
wouldn’t be an actual type