Generics 101: I have two interfaces that work toge...
# announcements
g
Generics 101: I have two interfaces that work together like this:
Copy code
interface FancyConnector<T : Transcoder<I, O>> : RawHttpConnector {
    val transcoder: T

    fun send(entity: I) = sendRaw(this.transcoder.encode(entity))
    fun receive(): O = this.transcoder.decode(receiveRaw())
}

interface Transcoder<I, O> {
    fun encode(entity: I): HttpBytes
    fun decode(raw: HttpBytes): O
}
How can I make the compiler recognise the
I
and
O
type generics? Or alternatively, how can I define my interfaces so that
FancyConnector
doesn't need to know the internal types of
Transcoder
? EDIT: Imagine there is a
class IdentityTranscoder<E> : Transcoder<E, E>
. I want to be able to use it like
class MyConnector<IdentityTranscoder<Foo>>
instead of having to specify
class MyConnector<Foo, Foo, IdentityTranscoder<Foo>>
s
What internal types?
g
When extending/implementing
FancyConnector
I only want to pass a
Transcoder
without the user having to worry what it actually encodes/decodes to
s
I take it
interface FancyConnector<I, O, T : Transcoder<I, O>>
isnt what you want then ?
g
No, not quite. Ideally, I want to be able to "deduce" the types without having to mention them explicitly. Something along the lines of having a
class OneToManyTranscoder<E> : Transcoder<E, List<E>>
that can be used like
FancyConnector<OneToManyTranscoder<Foo>>
(what I want) instead of having to (redundantly) mention
FancyConnector<Foo, List<Foo>, OneToManyTranscoder<Foo>>
(what you just suggested)
s
Best I can do is removing them when instantiating an instance of
FancyConnector
, not when subclassing:
Copy code
class AConnector<I, O, T : Transcoder<I, O>> : FancyConnector<I, O, T> {
    override val transcoder: T
        get() = TODO("not implemented")
}

class ATranscoder : Transcoder<String, String> {
    override fun encode(entity: String): String {
        throw NotImplementedError()
    }

    override fun decode(raw: String): String {
        throw NotImplementedError()
    }

}

fun <I, O, T : Transcoder<I, O>> deduceIAndO(trans: T) : FancyConnector<I, O, T> {
    return AConnector()
}

val foo = deduceIAndO(ATranscoder())
g
Thank you for trying in any case ❤️