Skip to content

Generic annotated type

Jonathan edited this page Aug 4, 2021 · 1 revision

A generic annotated type is a type whose the generic parameter is link to the type itself, rather than for a function, for example:

class Key<T>(val id: String)

class Map<K, V> {
    fun get(key: K): Option<V>
    fun set(key: K, value: V): Option<V>
}

val myKey = Key<String>("example")
val properties = HashMap<Key<?>, ?>()
val set = properties.set(myKey, "Example") // Impossible because String could not be casted to ?
val get = properties.get(myKey) // Returns ?

There is no way to ensure that when you call get(myKey) you will get a value of the same type as the T of myKey and you could not even prove that your set operation is valid. To overcome this, it is possible to use Generic Annotated Types:

class Key<T>(val id: String)

class Map<K, V> {
    fun get(key: K): Option<V>
    fun set(key: K, value: V): Option<V>
}

val myKey = Key<String>("example")
val properties = [T]HashMap<Key<T>, T>() // Annotate HashMap with [T]
val set = properties.set(myKey, "Example") // Possible
val get = properties.get(myKey) // Returns String

This is a variant of Generic Type annotated variables and fields, which is possible in Firefly as well:

class Key<T>(val id: String)

class Map<K, V> {
    fun get(key: K): Option<V>
    fun set(key: K, value: V): Option<V>
}

val myKey = Key<String>("example")
val properties<T> = HashMap<Key<T>, T>() // Annotate properties with <T>
val set = properties.set(myKey, "Example") // Possible
val get = properties.get(myKey) // Returns String

In the case above, instead of annotating the HashMap type, we annotate the properties variable.

Clone this wiki locally