0

I am practicing some functional programming with a sealed class List and a map function.

So far the code for the sealed class

sealed class List <T> {

    class Node <T> ( val head : T , val tail : List<T>) : List<T> () {
        override fun toString () =
            "${head.toString()} , ${tail.toString()}"
    }

    object Nil : List<Nothing> ()  {
        override fun toString () = "NIL"
    }

    companion object {
        operator
        fun <T> invoke (vararg values : T ) : List<T>{
            val empty = Nil as List<T>
            val res = values.foldRight( empty , { v, l -> l.addFirst(v)   })
            return res
        }
    }

    fun addFirst ( head : T ) : List<T> = Node (head , this)

    fun removeFirst ()  : List <T> = when (this) {
        is Nil -> throw IllegalStateException()
        is Node<T> -> this.tail
    }

}

The map function inside the sealed class worked fine, but now I want it to run outside the sealed class like

fun <T,R> map (list:List<T>, f: (T) -> R) {
    when(list) {
        is List.Nil -> List.Nil as List<R>
        is List.Node -> List.Node<R> (f(head), tail.map(f))
    }
}

But now "head" and "tail" don't work any longer, because of unresolved references. I tried different strategies, but nothings works. Any ideas how to solve it?

Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42
Momo
  • 73
  • 6
  • 6
    `list.head`, `list.tail`? – gidds Nov 27 '19 at 20:16
  • This was my first choice. But with : is List.Node -> List.Node (f (list.head), list.tail.map (f)) map doesn't work any longer – Momo Nov 28 '19 at 09:21
  • Found a solution after some more research fun List.map (f : (T) -> R) : List = when (this) { List.Nil -> List.Nil as List is List.Node -> List.Node (f(head), tail.map(f)) } – Momo Nov 28 '19 at 18:58

1 Answers1

0

Found a solution after some more research fun List.map (f : (T) -> R) : List = when (this) { List.Nil -> List.Nil as List is List.Node -> List.Node (f(head), tail.map(f)) }

Momo
  • 73
  • 6