Guest User

Untitled

a guest
Dec 10th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.63 KB | None | 0 0
  1. sealed trait TreeData
  2. // ...
  3.  
  4. // could be made generic in data
  5. case class Node(data: TreeData, children: List[Node])
  6.  
  7. sealed trait ZipCtx
  8. case object Top extends ZipCtx
  9. case class At(revLeft: List[Node], right: List[Node], ctx: ZipCtx, updata: TreeData) extends ZipCtx
  10.  
  11. // ZipTree(root, Top) is the start
  12. case class ZipTree(n: Node, ctx: ZipCtx) {
  13.  
  14. private def toOption[A, B](a: A)(pf: PartialFunction[A, B]): Option[B] =
  15. if (pf isDefinedAt a) Some(pf(a))
  16. else None
  17.  
  18. def left = toOption(ctx) {
  19. case At(l :: xs, r, ctx, d) => ZipTree(l, At(xs, n :: r, ctx, d))
  20. }
  21.  
  22. def right = toOption(ctx) {
  23. case At(l, r :: xs, ctx, d) => ZipTree(r, At(n :: l, xs, ctx, d))
  24. }
  25.  
  26. def down = toOption(n.children) {
  27. case c :: cs => ZipTree(c, At(Nil, cs, ctx, n.data))
  28. }
  29.  
  30. def up = toOption(ctx) {
  31. case At(l, r, upctx, d) => ZipTree(Node(d, (n :: l) reverse_::: r), upctx)
  32. }
  33. }
  34.  
  35. object ZipTree {
  36. private def bindApply(f: ZipTree => Option[ZipTree])(loc: Option[ZipTree]) = loc flatMap f
  37.  
  38. val left = bindApply(_.left) _
  39. val right = bindApply(_.right) _
  40.  
  41. def up = bindApply(_.up) _
  42.  
  43. def down = bindApply(_.down) _
  44.  
  45. def walk(start: Option[ZipTree])(path: Seq[Option[ZipTree] => Option[ZipTree]]) =
  46. (start /: path) {
  47. case (loc, f) => f(loc)
  48. }
  49.  
  50. def rightOf(tree: ZipTree): Stream[ZipTree] =
  51. tree.right map (r => Stream.cons(r, rightOf(r))) getOrElse Stream.empty
  52.  
  53. def children(zt: ZipTree): Stream[ZipTree] = zt.down map {
  54. leftmost =>
  55. Stream.cons(leftmost, rightOf(leftmost))
  56. } getOrElse Stream.empty
  57.  
  58. def childrenKeyed(zt: ZipTree, s: String): Stream[ZipTree] =
  59. children(zt) filter (_.n.data._1 == s)
  60. }
Add Comment
Please, Sign In to add comment