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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/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_Tree_Fold_Unfold_Anamorphism - Fatal编程技术网

Haskell-将玫瑰树的深度优先遍历表示为“展开”的实例,并通过代数推导

Haskell-将玫瑰树的深度优先遍历表示为“展开”的实例,并通过代数推导,haskell,tree,fold,unfold,anamorphism,Haskell,Tree,Fold,Unfold,Anamorphism,假设我们定义了一棵玫瑰树,以及相应的数据类型 data RTree a = Node a [RTree a] foldRTree :: (a -> [b] -> b) -> RTree a -> b foldRTree f (Node x xs) = f x (map (foldRTree f) xs) 这种结构的深度优先遍历的递归定义为: dft :: RTree a -> [a] dft (Node x xs) = x : concat (map dft x

假设我们定义了一棵玫瑰树,以及相应的数据类型

data RTree a = Node a [RTree a]

foldRTree :: (a -> [b] -> b) -> RTree a -> b
foldRTree f (Node x xs) = f x (map (foldRTree f) xs)
这种结构的深度优先遍历的递归定义为:

dft :: RTree a -> [a]
dft (Node x xs) = x : concat (map dft xs)
我们可以将dft表示为玫瑰树上的折叠,特别是我们可以通过代数推导出这样的折叠

// Suppose dft = foldRTree f
// Then foldRTree f (Node x xs) = f x (map (foldRTree f) xs) (definition of foldRTree)
// But also foldRTree f (Node x xs) = dft (Node x xs) (by assumption)
//                                 = x : concat (map dft xs) (definition of dft)

// So we deduce that f x (map (foldRTree f) xs) = x : concat (map dft xs)
// Hence f x (map dft xs) = x : concat (map dft xs) (by assumption)
// So we now see that f x y = x : concat y
我想我们之所以能够这样做是因为foldRTree捕获了RTrees上的一般递归结构,这就引出了我对unfold的查询

我们定义如下:

unfold :: (a -> Bool) -> (a -> b) -> (a -> a) -> a -> [b]
unfold n h t x | n x = []
               | otherwise = h x : unfold n h t (t x)


// Or Equivalently
unfold' n h t = map h . takeWhile (not.n) . iterate t
dft (Node x xs) = x : unfold null h t xs
                         where h ((Node a xs) : ys) = a
                               t ((Node a xs) : ys) = xs ++ ys
我们可以将深度优先遍历表示为展开,如下所示:

unfold :: (a -> Bool) -> (a -> b) -> (a -> a) -> a -> [b]
unfold n h t x | n x = []
               | otherwise = h x : unfold n h t (t x)


// Or Equivalently
unfold' n h t = map h . takeWhile (not.n) . iterate t
dft (Node x xs) = x : unfold null h t xs
                         where h ((Node a xs) : ys) = a
                               t ((Node a xs) : ys) = xs ++ ys
我正在努力寻找一种方法来发展一种代数计算函数nht的方法,就像cons一样。特别是在开发展开时,有一个巧妙的步骤,即认识到展开的最终参数必须是[RTree a]类型,而不仅仅是RTree a。因此,向dft提出的论点没有直接传递给展开,因此我们在对这两个函数进行推理时遇到了障碍


如果有人能提供一种数学方法来对展开进行推理,从而在将递归函数(自然是折叠)表示为展开(可能使用一些将折叠和展开联系起来的定律)时计算出所需的函数nh和t,我将不胜感激。一个自然的问题是,我们必须用什么方法来证明这种关系是正确的

提示:将内部状态类型为
s
且输出列表类型为
[a]
的展开类型定义为
类型展开sa=(s->Bool,s->a,s->s,s)
。这些很像列表;您的函数基本上具有类型
unfold::unfold s a->[a]
。你会写
cons::a->Unfold s a->Unfold吗?您选择的某种类型的
?<代码>地图::(a->b)->展开s a->展开?b<代码>混凝土::展开s(展开s'a)->展开?a?如果您有
cons
map
concat
,您可以使用相同的定义(但不同的类型)直接写下您的
dft