将函数映射到Haskell中的BST

时间:2015-06-03 21:14:25

标签: haskell

假设我的数据类型为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中树的实现)

1 个答案:

答案 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 = Nothingfmap f (Just a) = Just (f a)。此外,根据定义,任何MonadApplicative也是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

那就是你所要做的一切!