Skip to content

Instantly share code, notes, and snippets.

@sderosiaux
Created May 2, 2018 09:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sderosiaux/984a3b69acad8d0e60b9da8918a9644a to your computer and use it in GitHub Desktop.
Save sderosiaux/984a3b69acad8d0e60b9da8918a9644a to your computer and use it in GitHub Desktop.
object Tree {
sealed trait Tree[A]
case class Leaf[A](a: A) extends Tree[A]
case class Node[A](left: Tree[A], right: Tree[A]) extends Tree[A]
def translate[A, B, C, F[_], E](t: Tree[A], check: (A, B) => Boolean, newState: B => B, endState: (A, B) => C, err: A => E)(implicit F: MonadError[F, E]): StateT[F, B, Tree[C]] = t match {
case Leaf(a) => StateT(s => if (check(a, s)) F.raiseError(err(a)) else F.pure((newState(s), Leaf(endState(a, s)))))
case Node(left, right) =>
implicit val A = Apply[StateT[F, B, ?]]
(translate(left, check, newState, endState, err), translate(right, check, newState, endState, err)).mapN(Node.apply)
}
}
val t = Node(Node(Leaf("a"), Leaf("b")), Leaf("c"))
println(translate[String, Int, Int, Either[Error, ?], Error](t, (_, y) => y > 1, _ + 1, (_, y) => y, x => new Error(s"boom at $x")).runA(0))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment