Skip to content

Instantly share code, notes, and snippets.

@kioba
Created September 1, 2019 13:06
Show Gist options
  • Save kioba/c2ad1d90906f4acd974e3f871736ab99 to your computer and use it in GitHub Desktop.
Save kioba/c2ad1d90906f4acd974e3f871736ab99 to your computer and use it in GitHub Desktop.
Recursive ADT
package dev.kioba.ilist
sealed class IList<A>
class INil<A> : IList<A>()
class ICons<A>(val head: A, val tail: IList<A>) : IList<A>()
fun <A> iListOf(vararg arg: A): IList<A> =
arg.foldRight<A, IList<A>>(INil()) { element, acc -> ICons(element, acc) }
fun <A> IList<A>.forEach(f: (A) -> Unit): Unit =
fold(Unit) { element, _ -> f(element) }
fun <A, B> IList<A>.map(f: (A) -> B): IList<B> =
foldR<A, IList<B>>(INil()) { element, acc -> ICons(f(element), acc) }
fun <A, B> IList<A>.foldR(initial: B, f: (A, B) -> B): B = when (val it = this) {
is INil -> initial
is ICons -> f(it.head, it.tail.foldR(initial, f))
}
fun <A, B> IList<A>.fold(initial: B, f: (A, B) -> B): B = when (val it = this) {
is INil -> initial
is ICons -> it.tail.fold(f(it.head, initial), f)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment