Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 树声明之间的区别?_Haskell - Fatal编程技术网

Haskell 树声明之间的区别?

Haskell 树声明之间的区别?,haskell,Haskell,两者之间有什么区别 data Tree a = Leaf a | Node (a, Tree a, Tree a) deriving Show 及 注意:节点的括号有一个区别:在第一个括号中,节点是一个构造函数,有一个字段,一个元组。这意味着,当我们给它一个类型时,它的形式是节点::(a,treea,treea)->treea,一个直接指向树的函数。后者是一个具有3个字段的构造函数,因此该构造函数使用适当的curried函数类型化 现在看来,这两个声明是等价的,但在这两个声明中有多少间接性存在

两者之间有什么区别

data Tree a = Leaf a | Node (a, Tree a, Tree a) deriving Show


注意:节点的括号有一个区别:在第一个括号中,节点是一个构造函数,有一个字段,一个元组。这意味着,当我们给它一个类型时,它的形式是
节点::(a,treea,treea)->treea
,一个直接指向树的函数。后者是一个具有3个字段的构造函数,因此该构造函数使用适当的curried函数类型化

现在看来,这两个声明是等价的,但在这两个声明中有多少间接性存在着显著差异。在第一个例子中,我们有一个指向三个指针组成的元组的指针。在第二个例子中,构造函数中直接有3个指针。这可能会对效率产生一些影响(间接寻址总是这样),并且还会在第一个定义中引入一个额外的值,
节点未定义
(或者更一般地说,
节点124;
),后者没有明确的等价物

这是因为Haskell中的每一级间接性都让我们能够构造一个新的时髦的伪值,其中最外层的包装器求值,但间接性(提供惰性)指向一个不同的thunk。如果你用一种严格的语言来观察它们,你会发现它们是同构的,但严格地说,它们在Haskell模型中应该有不同的表示

对于惯用且更高效的代码,请选择后者。

另外请注意,
节点(树a)a(树a)
如果按顺序遍历该树特别有意义(例如,对于搜索树),则会比这两者都好,因为这将允许您使用
派生(可折叠、可遍历)
,并获得您可能想要的结果。
data Tree a = Leaf a | Node a (Tree a) (Tree a) deriving Show