我已经定义了一个名为Tree a
的多态数据类型,如下所示:
data Tree a = Leaf | Node a (Tree a) (Tree a)
我想定义一个函数mapT
,它接受一个函数并将其应用于a
类型树中Tree a
类型的每个数据项。这个函数的基本目的是以map
函数在列表上运行的方式对树进行操作,因此我根据这个想法编写了一个函数:
mapT :: (a -> b) -> Tree a -> Tree b
mapT f Leaf = Leaf
mapT f ((Tree a) left right) = (Tree a) (mapT f left) (mapT f right)
然而,当我运行这个时,我得到一个Parse error in pattern: (Tree a)
,我无法弄清楚出了什么问题。有谁知道如何通过这个?
答案 0 :(得分:2)
尝试:
data Tree a = Leaf | Node a (Tree a) (Tree a)
mapT :: (a -> b) -> Tree a -> Tree b
mapT f Leaf = Leaf
mapT f (Node a left right) = Node (f a) (mapT f left) (mapT f right)
请注意,您的Leaf
构造函数没有与is关联的任何数据,因此您可能真的想要:
data Tree a = Leaf a | Node ...
mapT
中的相应更改。
此外,一旦您mapT
为您工作,您应该阅读Functor
类型类,以及为什么您可能想为{{1}创建Functor
实例}}:
Tree a
答案 1 :(得分:2)
Tree
是一个类型构造函数,而不是数据构造函数。你可能意味着Node
。
错误消息试图告诉您不能在模式中使用任意应用程序。您只能匹配完全应用的构造函数,因此(Node a left right)
是有效模式而((Node a) left right)
不是,即使两者都作为表达式有效。
您需要将f
应用于a
,以便将b
类型的内容放入转换后的节点中。否则,类型检查器会抱怨a
与b
无法匹配。
最终结果应如下所示:
mapT :: (a -> b) -> Tree a -> Tree b
mapT f Leaf = Leaf
mapT f (Node a left right) = Node (f a) (mapT f left) (mapT f right)