[英]Tree as instance of functor and foldable
I am writing a little code for a hw problem which asks us to make a definition of tree an instance of functor and foldable. 我正在为一个hw问题编写一些代码,它要求我们将树的定义作为functor和foldable的一个实例。 When I write the code below: 当我写下面的代码时:
import Data.Foldable
import Data.Monoid
data Tree a = Leaf a
| Node [Tree a]
deriving (Show)
instance Functor (Tree) where
fmap f (Leaf a) = Leaf (f a)
fmap f (Node [Tree a]) = fmap f [Tree a]
instance Foldable (Tree) where
foldMap f (Leaf a) = f a
foldMap f (Node [Tree a]) = foldMap f `mappend` [Tree a]
the following error appears: 出现以下错误:
hw.hs:10:19:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)
hw.hs:10:38:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)
hw.hs:14:22:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)
hw.hs:14:54:
Not in scope: data constructor `Tree'
Perhaps you meant `True' (imported from Prelude)
Failed, modules loaded: none.
Where am I going wrong? 我哪里错了?
Thanks! 谢谢!
[[Update]] [[更新]]
I have made changes to the code as per the suggestion made in the answer below. 我根据下面答案中的建议对代码进行了更改。 Here is a link to the code with the error. 这是带错误的代码的链接。 It would be great if anyone would take a look at it and tell me where I am wrong. 如果有人看看它并告诉我哪里错了,那就太好了。
http://snipt.org/Bahjg5 http://snipt.org/Bahjg5
Thanks again! 再次感谢!
You can't write this: 你不能写这个:
fmap f (Node [Tree a]) = ...
because Tree
is a data type not a data constructor. 因为Tree
是数据类型而不是数据构造函数。 In a pattern-match you can only use data constructors, which would be Leaf
or Node
in this case. 在模式匹配中,您只能使用数据构造函数,在这种情况下,它们将是Leaf
或Node
。 Here, you don't even need to match each constructor for the child trees, because you are passing the entire list straight through anyway: 在这里,您甚至不需要匹配子树的每个构造函数,因为您无论如何都要直接传递整个列表:
fmap f (Node t) = fmap f t
But actually there is also another error there. 但实际上还存在另一个错误。 The result of fmap
still needs to be a Tree
so you need to put the result back inside a Node
: fmap
的结果仍然需要是Tree
因此您需要将结果放回Node
:
fmap f (Node t) = Node (fmap f t)
just like you are already doing with the Leaf
case. 就像你已经在使用Leaf
案一样。
You can think of fmap
as something that modifies values inside the structure, but without changing the shape of the structure at all. 您可以将fmap
视为修改结构内部值的内容,但根本不会更改结构的形状 。 ie. 即。 mapping over a list will produce a list of the same length, and mapping over a tree should produce an identical tree, with all the same branches, but with different values in the leaf nodes. 在列表上进行映射将生成相同长度的列表,并且在树上的映射应该生成相同的树,具有所有相同的分支,但在叶节点中具有不同的值。
You can think of a fold
as something that completely removes the structure, and then finds a way to combine all the values from leaf nodes into a single value. 您可以将fold
视为完全删除结构的东西,然后找到将叶节点中的所有值组合成单个值的方法。 The Type of foldMap
helps: foldMap
的类型有助于:
foldMap :: (Foldable t, Monoid m) =>
(a -> m) -- mapping function from `a` to the monoid result
-> t a -- A tree node containing values of type `a`
-> m -- a monoid
The result of foldMap
should not be a Tree
! foldMap
的结果不应该是Tree
! It's just the values, transformed with the mapping function and combined using their Monoid
instance. 它只是值,使用映射函数进行转换,并使用它们的Monoid
实例进行组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.