我正在努力解决这个问题:
编写折叠函数,将函数折叠在树上。 (因此,为 例如,
fold min t
将在树中找到最小的元素。)fold :: (a -> a -> a) -> Tree -> a
*那是我的剧本
data Tree = Leaf Int
| Fork Tree Int Tree
deriving Show
t0 = Leaf 0
t1 = Fork (Fork (Leaf 1) 2 (Leaf 3)) 4 (Fork (Leaf 5) 6 (Leaf 7))
t2 = Fork (Fork (Fork (Leaf 1) 2 (Leaf 3)) 4 (Leaf 5)) 6 (Leaf 7)
fold :: (a -> a -> a) -> Tree -> a
fold f v (Leaf n) = v
fold f v (Fork l n r) = f (Folk l) (fold f v (Fork r))
感谢您的任何建议
答案 0 :(得分:4)
有一件事,在你的函数fold
的签名中,你说它会收到2个参数,一个二元函数(可能是一个运算符),一个Tree并返回一个{ {1}}。现在,在定义中你有3个参数,a
,一些f
和一个v
的构造函数。
解决方案可能就是这个:
Tree
您需要说明的是fold :: (Int -> Int -> Int) -> Tree -> Int
fold f (Leaf n) = n
fold f (Fork l n r) = f n m
where
m = f (fold f l) (fold f r)
,因为Int
占有Tree
。
修改强>
此外,您可以使用刚性类型变量重新定义数据。
Int
我建议你阅读Data.Foldable的文档。他们有一个data Tree a = Leaf a
| Fork (Tree a) a (Tree a)
deriving Show
fold :: (a -> a -> a) -> Tree a -> a
fold f (Leaf n) = n
fold f (Fork l n r) = f n m
where
m = f (fold f l) (fold f r)
数据类型的示例。
答案 1 :(得分:3)
折叠可以在某种程度上机械地衍生自任何类型。这是foldMaybe
:
data Maybe a = Nothing | Just a
foldMaybe :: r -> (a -> r) -> Maybe a -> r
foldMaybe _ k (Just a) = k a
foldMaybe d _ Nothing = d
To" fold"数据类型意味着我们将提供一种方法,将该类型的每个可能的构造函数组合成最终类型r
。这里,Maybe
有两个构造函数:一个值为0,另一个值为a
。因此,要折叠它,我们需要为Nothing
案例提供一个值,并将Just a
转换为r
。
让我们看看list
,看看foldr
是如何从中得到的。
data List a = Nil | Cons a (List a)
[1] [2 3 4] [4]
foldList :: r -> (a -> r -> r) -> List a -> r
Nil
时要使用的值。Cons
案例的函数。由于Cons
的第一个值为a
,因此该函数必须采用a
。Cons
所采用的第二个值是(List a)
,那么为什么我们选择r
?好!我们正在定义一个可以使用List a
并返回r
的函数,因此在与当前节点合并之前,我们将处理列表的其余部分。r
。实现是什么样的?
foldList nil cons list = case list of
Nil -> nil
Cons a as -> cons a (foldList nil cons list)
所以我们用"析构函数替换所有构造函数"同行,必要时递归。
树木:
data Tree = Leaf Int | Fork Tree Int Tree
我们有两个构造函数:一个使用Int
,另一个使用三个参数Tree
,Int
和Tree
。
让我们写一下类型签名!
treeFold :: LeafCase r -> ForkCase r -> r
啊,但我们必须定义LeafCase
:
type LeafCase r = Int -> r
由于Leaf
将一个Int作为参数,因此该函数的类型必须是什么。
type ForkCase r = r -> Int -> r -> r
同样,我们将Tree
中Fork
的所有递归用法替换为r
类型参数。所以我们的全部功能如下:
foldTree :: (Int -> r) -> (r -> Int -> r -> r) -> Tree -> r
实施可能会开始:
foldTree leaf fork tree = case tree of
Leaf i -> error "halp"
Fork l i r -> error "complete me?"
我相信你可以填补这些漏洞:)