Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- sealed abstract class PathElement
- object PathElement {
- case class Property (name : String) extends PathElement
- case class Index (index: Int) extends PathElement
- case class Named (name : String) extends PathElement
- }
- type Path = List[PathElement]
- sealed abstract class AnyTransformerFailure
- object AnyTransformerFailure {
- case class Message (message : String) extends AnyTransformerFailure
- case class Exception(throwable: Throwable) extends AnyTransformerFailure
- }
- sealed abstract class AnyTransformerTree
- object AnyTransformerTree {
- case class Empty () extends AnyTransformerTree
- case class Leaf (path: Path, failure: AnyTransformerFailure) extends AnyTransformerTree
- case class Suppress (tree: AnyTransformerTree) extends AnyTransformerTree
- case class Fork (left: AnyTransformerTree, right: AnyTransformerTree) extends AnyTransformerTree
- val empty = Empty()
- def leaf(p: Path)(f: AnyTransformerFailure) = Leaf(p, f)
- def suppress(t: AnyTransformerTree) = {
- t match {
- case _ : Suppress => t
- case _ => Suppress(t)
- }
- }
- def fork(l: AnyTransformerTree, r: AnyTransformerTree) = {
- (l, r) match {
- case (_: Empty , _ ) => r
- case (_ , _: Empty ) => l
- case (l: Suppress , r: Suppress ) => Suppress(Fork(l, r))
- case _ => Fork(l, r)
- }
- }
- }
- case class AnyTransformerResult[+A](value: A, tree: AnyTransformerTree)
- object AnyTransformerResult {
- @inline def result[A](v: A, t: AnyTransformerTree) = AnyTransformerResult[A](v, t)
- @inline def good [A](v: A) = result(v, AnyTransformerTree.empty)
- }
- case class AnyTransformer[+A](f: (Any, Path) => AnyTransformerResult[A])
- object AnyTransformer {
- import AnyTransformerResult._
- import AnyTransformerTree._
- // Monad
- def unit[A](a: A): AnyTransformer[A] =
- AnyTransformer((v, p) => good(a))
- def bind[A,B](a: AnyTransformer[A])(bf: A => AnyTransformer[B]): AnyTransformer[B] =
- AnyTransformer((v, p) => {
- val ar = a.f(v, p)
- val b = bf(ar.value)
- val br = b.f(v, p)
- result(br.value, fork(ar.tree, br.tree))
- })
- // Applicative
- def ap[A,B](f: AnyTransformer[A => B])(a: AnyTransformer[A]): AnyTransformer[B] =
- AnyTransformer((v, p) => {
- val fr = f.f(v, p)
- val ar = a.f(v, p)
- result(fr.value(ar.value), fork(fr.tree, ar.tree))
- })
- // Functor
- def map[A,B](m: A => B)(a: AnyTransformer[A]): AnyTransformer[B] =
- AnyTransformer((v, p) => {
- val ar = a.f(v, p)
- result(m(ar.value), ar.tree)
- })
- }
- object Main extends App {
- println("Hello")
- }
Add Comment
Please, Sign In to add comment