Skip to content
Snippets Groups Projects
BinTree.scala 1.44 KiB
Newer Older
Martin Ring's avatar
Martin Ring committed
// Binary trees with functional updates.

enum Tree[+A]:
  case Leaf(value: A)
  case Node(left: Tree[A], 
            right: Tree[A])

enum Context[+A]:
  case object Empty
  case Left(up: Context[A], 
            right: Tree[A])
  case Right(left: Tree[A], 
             up: Context[A])

  case Loc(tree: Tree[A], context: Context[A])


    def goLeft: Loc[A] = context match
      case Empty => sys.error("goLeft at empty")
      case Left(_,_) => sys.error("goLeft of left")
      case Right(l,c) => Loc(l,Left(c,tree))


    def goRight: Loc[A] = context match
      case Empty => sys.error("goRight at empty")
      case Left(c,r) => Loc(r,Right(tree,c))
      case Right(_,_) => sys.error("goRight of right")


    def goUp: Loc[A] = context match
      case Empty => sys.error("goUp of empty")
      case Left(c,r) => Loc(Node(tree,r),c)
      case Right(l,c) => Loc(Node(l,tree),c)


    def goDownLeft: Loc[A] = tree match
      case Leaf(_) => sys.error("goDown at leaf")
      case Node(l,r) => Loc(l,Left(context,r))


    def goDownRight: Loc[A] = tree match
      case Leaf(_) => sys.error("goDown at leaf")
      case Node(l,r) => Loc(r,Right(l,context))


    def insertLeft(t: Tree[A]): Loc[A] =
      Loc(tree,Right(t,context))

    def insertRight(t: Tree[A]): Loc[A] =
      Loc(tree,Left(context,t))

    def delete: Loc[A] = context match
      case Empty => sys.error("delete of empty")
      case Left(c,r) => Loc(r,c)
      case Right(l,c) => Loc(l,c)