Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package java2scala.homeworks.funcs
- trait ChurchList[A] {
- def fold[B](z: B)(f: A => B => B): B
- def ::(x: A): ChurchList[A] = new ChurchList.Cons[A](this, x)
- def map[B](f: A => B): ChurchList[B] = fold(ChurchList.empty[B])(e => acc => f(e) :: acc)
- def filter(f: A => Boolean): ChurchList[A] = fold(ChurchList.empty[A])(e => acc => if (f(e)) e :: acc else acc)
- def flatMap[B](f: A => ChurchList[B]): ChurchList[B] = fold(ChurchList.empty[B])(e => acc => f(e) ++ acc)
- def headOption: Option[A] = fold(Option.empty[A])(e => _ => Some(e))
- def drop(count: Int): ChurchList[A] =
- fold((ChurchList.empty[A], 0))(e => acc => if (acc._2 < count) (acc._1, acc._2 + 1) else (e :: acc._1, acc._2 + 1))._1
- def toList: List[A] = fold(List[A]())(e => acc => e :: acc)
- def ++(that: ChurchList[A]): ChurchList[A] = fold(that)(e => acc => e :: acc)
- }
- object ChurchList {
- def apply[A](xs: A*): ChurchList[A] = {
- def go(seq: Seq[A], acc: ChurchList[A]): ChurchList[A] = seq match {
- case Seq() => acc
- case h +: tail => go(tail, h :: acc)
- }
- go(xs.reverse, empty[A])
- }
- def empty[A]: ChurchList[A] = new ChurchList[A] {
- override def fold[B](z: B)(f: A => B => B): B = z
- }
- class Cons[A] private[ChurchList] (list: ChurchList[A], x: A) extends ChurchList[A] {
- override def fold[B](z: B)(f: A => B => B): B = f(x)(list.fold(z)(f))
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement