dflemstr 的答案是正确的,但我想我会添加两个评论(不能通过对原始答案的评论来容纳)。
首先,按照第二个定义可以节省内存的相同逻辑,可以为这个定义一个类似的论点:
data Tree a = Empty
| Leaf a
| LeftOnly a (Tree a)
| RightOnly a (Tree a)
| Branch a (Tree a) (Tree a)
这是否真的重要取决于您的应用程序。
第二个也是更重要的一点是,如果您避免直接使用数据构造函数,您可以从这些实现选择中抽象出来。例如,foldTree
可以为这些类型中的任何一种编写等效函数。对于较短的类型,您可以这样做:
data Tree a = Empty | Node a (Tree a) (Tree a)
foldTree :: (a -> b -> b -> b) -> b -> Tree a -> b
foldTree f z Empty = z
foldTree f z (Node v l r) = f v (subfold l) (subfold r)
where subfold = foldTree f z
对于更长的,你可以这样写:
data Tree a = Empty | Leaf a | Node a (Tree a) (Tree a)
foldTree :: (a -> b -> b -> b) -> b -> Tree a -> b
foldTree f z Empty = z
foldTree f z (Leaf v) = f v z z
foldTree f z (Node v l r) = f v (subfold l) (subfold r)
where subfold = foldTree f z
对于您Maybe
的基于 - 的替代方案或我的五构造函数替代方案也可以这样做。此外,这种技术可以应用于您需要的树上的任何其他通用函数。(事实上,很多这样的函数都可以用 来写foldTree
,所以大部分都超出了上面的定义。)