/***
coursier.CoursierPlugin.projectSettings
scalaVersion := "2.11.8"
libraryDependencies += "com.slamdata" %% "matryoshka-core" % "0.16.1"
*/

import matryoshka._
import matryoshka.implicits._

object Main extends App {

  sealed trait Expr[A]
  final case class Num[A](value: Long) extends Expr[A]
  final case class Mul[A](l: A, r: A) extends Expr[A]

  // we will need a Functor[Expr] in order to call embed bellow

  implicit val exprFunctor = new scalaz.Functor[Expr] {
    override def map[A, B](fa: Expr[A])(f: (A) => B) = fa match {
      case Num(value) => Num[B](value)
      case Mul(l, r)  => Mul(f(l), f(r))
    }
  }

  val eval: Algebra[Expr, Long] = { // i.e. Expr[Long] => Long

    case Num(x)    => x
    case Mul(x, y) => x * y
  }

  def someExpr[T](implicit T: Corecursive.Aux[T, Expr]): T =
    Mul(Num[T](2).embed, Mul(Num[T](3).embed,
      Num[T](4).embed).embed).embed

  import matryoshka.data.Mu

  val r = someExpr[Mu[Expr]].cata(eval) // ⇒ 24


  println(r)

}

        
  
Processing...
Reused last reload result
[info] Loading project definition from /tmp/rendererxR5Pmthmph/project/project
[info] Loading project definition from /tmp/rendererxR5Pmthmph/project
[warn] Discarding 33 session settings.  Use 'session save' to persist session settings.
[info] Set current project to rendererWorker (in build file:/tmp/rendererxR5Pmthmph/)
[info] Reapplying settings...
[info] Set current project to rendererWorker (in build file:/tmp/rendererxR5Pmthmph/)
[info] Formatting 1 Scala source {file:/tmp/rendererxR5Pmthmph/}rendererWorker(compile) ...
[info] Reformatted 1 Scala source {file:/tmp/rendererxR5Pmthmph/}rendererWorker(compile).
[info] Compiling 1 Scala source to /tmp/rendererxR5Pmthmph/target/classes...
[success] Total time: 18 s, completed Dec 25, 2016 10:08:47 AM
Now running...
[info] Running Main 
24
[success] Total time: 1 s, completed Dec 25, 2016 10:08:48 AM