我想在Scala中實現類型安全perfect binary tree。換句話說以下應編譯:Scala中的類型安全完美二叉樹
Succ(Node(Leaf("a"), Leaf("b")))
Node(
Succ(Node(Leaf("a"), Leaf("b"))),
Succ(Node(Leaf("c"), Leaf("d"))))
但以下不宜:
Node(
Succ(Node(Leaf("a"), Leaf("b"))),
Leaf("c"))
我想出了下面滿足上述但一個可以欺騙編譯器的解決方案:
Node(
Leaf("f"): PerfectBinaryTree,
Succ(Node(Leaf("a"), Leaf("b"))): PerfectBinaryTree)
有沒有辦法在Scala中避免這種情況? 與Haskell(如果有的話)有什麼不同?
trait PerfectBinaryTree {
type N <: PerfectBinaryTree
}
case class Succ[P <: PerfectBinaryTree](p: P) extends PerfectBinaryTree {
type N = Succ[P]
}
class Leaf[T] private (t: T) extends PerfectBinaryTree {
type N = Leaf[T]
}
object Leaf {
def apply[T](t: T): Leaf[T] = new Leaf(t)
}
case class Node[A <: PerfectBinaryTree, B <: PerfectBinaryTree](l: A, r: B)(implicit evidence: A =:= B) extends PerfectBinaryTree {
type N = A
}
您在問題中有兩個問題。我建議你在這個問題中刪除對Haskell的任何引用,並最終要求在Haskell中實現這個相關問題。 – Bakuriu
在Haskell中,這將是'data PerfectBinaryTree a = Zero a | Succ(PerfectBinaryTree(BinaryNode a))'和'數據BinaryNode a =節點a a'。你似乎已經搞亂了你的Scala代碼中的這個結構。 「葉」應該是「零」嗎?爲什麼他們都是同一班的情況? – Bergi
很可能@Bergi,我搞砸了。是啊'葉=零'。 如何安排回去? ;) 我會考慮這個@Bakuriu – mjaskowski