Created
November 22, 2014 13:19
-
-
Save prassee/c13dd602db4c55ae56cf to your computer and use it in GitHub Desktop.
FLIst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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