Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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_Functional Programming_Binary Tree - Fatal编程技术网

尝试在Haskell中使用顺序遍历展平树

尝试在Haskell中使用顺序遍历展平树,haskell,functional-programming,binary-tree,Haskell,Functional Programming,Binary Tree,尝试使用给定的fold函数将树展平为列表 treeFold :: (b -> a -> b -> b) -> b -> Tree a -> b treeFold _ b Leaf = b treeFold f b (Node lt x rt) = f (treeFold f b lt) x (treeFold f b rt) 以下是我到目前为止所尝试的: treeToList :: Tree a -> [a] treeToList =

尝试使用给定的fold函数将树展平为列表

treeFold :: (b -> a -> b -> b) -> b -> Tree a -> b
treeFold _ b Leaf         = b
treeFold f b (Node lt x rt) = f (treeFold f b lt) x (treeFold f b rt)
以下是我到目前为止所尝试的:

treeToList :: Tree a -> [a]
treeToList = treeFold (\xs x ys -> xs ++ x : ys) (\x -> [x])
出于某种原因,我不太明白该怎么做? 感觉Haskell有些事我还没想清楚。任何帮助以及如何着手解决问题都将不胜感激。 谢谢

编辑:


我意识到我在这里使用的类型签名近乎荒谬。在treeFold的类型签名中,根据我的想法,第二个参数(b)可能是一个列表,因为在本例中它以某种方式充当累加器。这将使第三个参数(树a)成为等式左侧参数的某个版本。函数中的两个参数必须是节点中的左子树和右子树。第三个参数只是节点的值。在函数中,我需要以通常的顺序方式组合左树、右树和值,但我尝试的所有不同变体都有一些问题

树的类型是

treeFold :: (b -> a -> b -> b) -> b -> Tree a -> b
您想返回一个值列表,
[a]

因此,结果类型
b
必须等于
[a]
,给我们一个

treeFold :: ([a] -> a -> [a] -> [a]) -> [a] -> Tree a -> [a]
请注意,第二个参数的类型为
[a]

您要传递什么值?

类型必须适合:

treeFold ::           ( b -> a -> b -> b              ) -> b -> Tree a -> b

treeToList = treeFold (\xs   x    ys -> xs ++ (x : ys))    z
-------------------------------------------------------------------
                        b    a    b     b      a   b       b
                                              --------
                                              b
由于
x
ys
参与相同的
,因此它们的类型必须兼容:

(:) ::   a  -> [a]  ->  [a]
x   ::   a
ys  ::          b
-------------------
              b ~ [a]
因此,我们有

treeFold ::           ( [a] -> a -> [a] -> [a]           ) -> [a] -> Tree a->[a]

treeToList = treeFold (\ xs    x    ys  -> xs ++ (x : ys))     z
-------------------------------------------------------------------
                         [a]   a    [a]    [a]    a   [a]     [a]
                                                 --------
                                                 [a]
结论:最后一个参数
z
的类型必须为
[a]

这个论点的意义是什么?与折叠一样,数据类型定义中的每个“变量”都有一个对应于折叠函数的参数

您的(缺少)数据类型定义是:

data Tree a = Node (Tree a)    a   (Tree a)       | Leaf
褶皱的类型是

treeFold ::   (         b  ->  a  ->  b  -> b )   ->  b     -> Tree a -> b
它对应于

因此,
z
是“将每个
Leaf
转换为的值”


最自然的选择就是
[]
。实际上,这是唯一的选择,因为我们还不知道
a
(在
[a]
中)的类型。

这里做什么
(\x->[x])
?啊,这很有意义。我想我还是刚刚开始了解Haskell中函数的应用,以及使用提供的类型对参数进行推理的方法。非常感谢。最重要的是,不要害怕类型!类型是你的朋友!(说真的,不像那部《火星袭击》电影:)至于应用程序,主要是这样的:对于
f::a->b->c->d
,我们有
f(x::a)::b->c->d
,和
f(x::a)(y::b)::c->d
,以及
f(x::a)(y::b)(z::c)::d
。这就是全部!
data TreeF a r = NodeF  r      a      r           | LeafF