Created
November 27, 2013 13:13
-
-
Save YoEight/7675419 to your computer and use it in GitHub Desktop.
Mu exercise (Scala 2.10)
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
| import scala.language.higherKinds | |
| trait Functor[F[_]] { | |
| def map[A, B](fa: F[A])(f: A => B): F[B] | |
| } | |
| object Functor { | |
| def apply[F[_], A, B](fa: F[A])(f: A => B)(implicit F: Functor[F]): F[B] = | |
| F.map(fa)(f) | |
| } | |
| case class Mu[F[_]](in: F[Mu[F]]) { | |
| def cata[B](f: F[B] => B)(implicit F: Functor[F]): B = | |
| f(F.map(in)(_.cata(f))) | |
| } | |
| sealed trait ListOp[+A,+B] | |
| case class Cons[A, B](head: A, tail: B) extends ListOp[A, B] | |
| case object Empty extends ListOp[Nothing, Nothing] | |
| object ListOp { | |
| type List[A] = Mu[({ type F[x] = ListOp[A, x] })#F] | |
| implicit def listOpFunctor[E] = | |
| new Functor[({ type F[x] = ListOp[E, x]})#F] { | |
| def map[A, B](fa: ListOp[E, A])(f: A => B): ListOp[E, B] = fa match { | |
| case Empty => Empty | |
| case Cons(e, a) => Cons(e, f(a)) | |
| } | |
| } | |
| def cons[A](head: A, tail: List[A]): List[A] = | |
| Mu[({ type F[x] = ListOp[A, x]})#F](Cons(head, tail)) | |
| def empty[A]: List[A] = | |
| Mu[({ type F[x] = ListOp[A, x] })#F](Empty) | |
| def singleton[A](x: A): List[A] = | |
| cons(x, empty) | |
| } | |
| object Exo { | |
| type List[A] = ListOp.List[A] | |
| /* Every List function should use Mu.cata function */ | |
| def map[A, B](xs: List[A])(f: A => B): List[B] = ??? | |
| def append[A](xs: List[A], vs: List[A]): List[A] = ??? | |
| def filter[A](xs: List[A])(f: A => Boolean): List[A] = ??? | |
| // Bonus: Don't traverse the entire List when non Empty | |
| def isEmpty[A](xs: List[A]): Boolean = ??? | |
| def flatMap[A, B](xs: List[A])(f: A => List[B]): List[B] = ??? | |
| def head[A](xs: List[A]): A = ??? | |
| def tail[A](xs: List[A]): List[A] = ??? | |
| // Bonus: Don't traverse the entire List when element is found | |
| def find[A](xs: List[A])(f: A => Boolean): Option[A] = ??? | |
| // Bonus: Don't traverse the entire List when false | |
| def all[A](xs: List[A])(f: A => Boolean): Boolean = ??? | |
| // Bonus: Don't traverse the entire List when true | |
| def any[A](xs: List[A])(f: A => Boolean): Boolean = ??? | |
| def foldRight[A, B](xs: List[A], b: B)(f: (A, B) => B): B = ??? | |
| def foldLeft[A, B](xs: List[A], b: B)(f: (B, A) => B): B = ??? | |
| def reverse[A](xs: List[A]): List[A] = ??? | |
| def zip[A, B](as: List[A], bs: List[B]): List[(A, B)] = ??? | |
| def zipWith[A, B, C](as: List[A], bs: List[B])(f: (A, B) => C): List[C] = ??? | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment