The Algebra of Types
Justin Hewlett

Kotlin supports sum types via the sealed keyword. You could model this in Kotlin like so:

sealed class T
class N(val v: Int, val l: T = E, val r: T = E) : T()
object E : T()

And instances are created like this:

val ta = N(3)           
val tb = N(3, E, N(4))

Use pattern matching to compute deep value:

val T.vDeep: Int
get() = when (this) {
is N -> v + l.vDeep + r.vDeep
is E -> 0
//called like this:
check(ta.vDeep == 3)
check(tb.vDeep == 7)

However, in Kotlin it might be more idiomatic to model the types like this:

class T(val v: Int, val l: T? = null, val r: T? = null)

and create instances like this:

val ta = T(3) 
val tb = T(3, null, T(4))

Instead of pattern matching to compute the deep value, just do this:

val T.vDeep: Int get() = (l?.vDeep ?: 0) + v + (r?.vDeep ?: 0)
//called like this:
check(ta.vDeep == 3)
check(tb.vDeep == 7)