Skip to content

Instantly share code, notes, and snippets.

@YoEight
Created November 27, 2013 13:13
Show Gist options
  • Select an option

  • Save YoEight/7675419 to your computer and use it in GitHub Desktop.

Select an option

Save YoEight/7675419 to your computer and use it in GitHub Desktop.
Mu exercise (Scala 2.10)
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