Skip to content

Instantly share code, notes, and snippets.

@prassee
Created November 22, 2014 13:19
Show Gist options
  • Save prassee/c13dd602db4c55ae56cf to your computer and use it in GitHub Desktop.
Save prassee/c13dd602db4c55ae56cf to your computer and use it in GitHub Desktop.
FLIst
package ch3
object FListDemo extends App {
/*
val list = FList("a", "b", "c")
println("printing tail of non empty list " + FList.tail(list))
println(FList.setHead("z", list))
val ex1 = FList(1, 2, 3, 4, 5) match {
case Cons(h, t) => println(t)
}
println(FList.drop(list, 2))
println(FList.dropWhile(FList(1, 2, 3, 4, 5), (y: Int) => y >= 3))
val curr = FList.currDropWhile(FList(1, 2, 3, 4, 5))(x => x < 8)
println(FList.foldRight(ints, 1)((x, y) => x * y))
println(FList.size(ints))
*/
val ints = FList(1, 2, 3, 4)
println(FList.reverse(ints, FNil))
println(FList.map[Int, Int](ints, x => x + 1), FNil)
println(FList.map[Int, Double](ints, x => Double.box(x)))
println(List(1, 2, 3).map(x => x + 1))
}
sealed trait FList[+T]
case class Cons[T](h: T, t: FList[T]) extends FList[T]
case object FNil extends FList[Nothing]
object FList {
def apply[T](a: T*): FList[T] = {
if (a.isEmpty) FNil
else Cons(a.head, apply(a.tail: _*))
}
def head[T](list: FList[T]) = list match {
case Cons(h, t) => h
case FNil => throw new Exception("head of empty list")
}
def tail[T](list: FList[T]) = list match {
case Cons(h, t) => t
case FNil => throw new Exception("tail of empty list")
}
def setHead[T](head: T, list: FList[T]) =
list match {
case Cons(h, t) => Cons(head, list)
case FNil => Cons(head, FNil)
}
def drop[T](list: FList[T], n: Int) = {
def iter(lit: FList[T], loop: Int): FList[T] = {
if (loop < n) {
iter(tail(lit), loop + 1)
} else lit
}
iter(list, 0)
}
def dropWhile[T](list: FList[T], drop: T => Boolean): FList[T] = {
def iter(list: FList[T], acc: FList[T]): FList[T] = {
list match {
case Cons(h, t) => {
val newacc = if (!drop(h))
Cons(h, acc)
else acc
iter(tail(list), newacc)
}
case FNil => acc
}
}
iter(list, FNil)
}
def currDropWhile[T](list: FList[T])(drop: T => Boolean): FList[T] = {
def iterList(list: FList[T], acc: FList[T]): FList[T] = {
list match {
case Cons(h, t) => {
val newAcc = if (!drop(h))
Cons(h, acc)
else acc
iterList(tail(list), newAcc)
}
case FNil => acc
}
}
iterList(list, FNil)
}
def foldRight(list: FList[Int], init: Int)(acc: (Int, Int) => Int): Int = list match {
case Cons(h, t) => foldRight(tail(list), acc(h, init))(acc)
case FNil => init
}
def size[T](list: FList[Int]): Int = foldRight(list, init = 0)((x, y) => y + 1)
def rev[T](h: T, tail: FList[T]) = tail match {
case Cons(h, t) => Cons(head(tail), Cons(h, FNil))
case FNil => tail
}
def reverse[T](list: FList[T], acc: FList[T]): FList[T] = list match {
case Cons(h, t) => reverse(t, setHead(h, acc))
case FNil => acc
}
def map[S, T](list: FList[S], x: S => T): FList[T] = {
def loop(list: FList[S], acc: FList[T]): FList[T] = list match {
case Cons(h, t) => loop(t, Cons(x(h), acc))
case FNil => acc
}
loop(list, FNil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment