假设我的数据类型为BST:
data tree a = Empty | Node a (tree a) (tree a)
deriving (Show, Read, Eq)
我正在做一个简单的map函数来应用BST的每个元素。
treeMap :: (a -> b) -> tree a -> tree b
treeMap f (Empty) = Empty
treeMap f (Node left right) = Node (treeMap f left) (treeMap f right)
然而,它给我一个错误说:
Constructor `Node' should have 3 arguments, but has been given 2
In the pattern: Node left right
In the definition of `treeMap':
treeMap f (Node left right)
= Node (treeMap f left) (treeMap f right)
我该如何解决这个问题? (p / s不是作业问题,试图理解haskell中树的实现)
答案 0 :(得分:5)
您忘记了节点的值:
treeMap f (Node a left right) = Node (f a) (treeMap f left) (treeMap f right)
但您确实需要修复data
声明。数据类型必须以大写字母开头:
data Tree a = Empty | Node a (Tree a) (Tree a)
您的类型签名
treeMap :: (a -> b) -> Tree a -> Tree b
这实际上是Haskell中的一种常见模式,它的名称为Functor
,其映射函数名为fmap
。列表是最常见的Functor
之一,fmap
只是标准map
,但许多其他类型也是Functor
。从概念上讲,Functor
只是一个通用容器,您可以在其中将函数应用于每个元素。 Maybe
也是Functor
,其中fmap f Nothing = Nothing
和fmap f (Just a) = Just (f a)
。此外,根据定义,任何Monad
或Applicative
也是Functor
,因此如果您可以使用do
表示法,则可以在其上使用fmap
。
对于您的结构,您可以将其作为<{1}}类型类的实例
Functor
与instance Functor Tree where
fmap f Empty = Empty
fmap f (Node a left right) = Node (f a) (fmap f left) (fmap f right)
具有不同名称的定义完全相同。此外,如果你给它treeMap
扩展名,GHC实际上有能力为你推导出这个实现:
DeriveFunctor
那就是你所要做的一切!