2011-10-02 65 views
5

我的树被哈斯克尔地图的树木

data Tree a = Leaf a | Node (Tree a) (Tree a) 
     deriving (Show) 

定义我也宣布测试树。

myTree = Node (Node (Leaf 1) (Leaf 2)) (Leaf 3) 

我想要做的是创建一个函数maptree f它将作用于Leaf。更具体地讲,f x = x +1

然后maptree f myTree将返回

Node (Node (Leaf 2) (Leaf 3)) (Leaf 4) 

我的解决办法是

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree xl) (maptree xr) 

但它会返回下面的错误

Couldn't match expected type `Tree a' 
     against inferred type `Tree t -> Tree t' 
Probable cause: `maptree' is applied to too few arguments 
In the first argument of `Node', namely `(maptree xl)' 
In the expression: Node (maptree xl) (maptree xr) 

失败,模块加载: 没有。

但是,如果我这样做

maptree (Leaf a)= Leaf (a + 1) 
maptree (Node xl xr) = Node (maptree xl) (maptree xr) 

它不工作了。

我看不出第一个功能和第二个功能之间的区别。我如何得到错误?谢谢。

+1

我现在开始工作了。我笨...>< –

+0

应maptree F(节点X1 XR)=节点(maptree˚FXL)(maptree˚FXR)代替maptree F(节点X1 XR)=节点(maptree XL)(maptree XR) –

回答

3

一种愚蠢的方式不会忘记你递归更深(对于这种高阶函数)沿函数传递是使用一个辅助:

maptree f (Leaf a)  = Leaf (f a) 
maptree f (Node xl xr) = Node (go xl) (go xr) 
    where go = maptree f 

,或者(和也许更常见):

maptree f tree = go tree      -- or eta reduce: maptree f = go 
    where go (Leaf a)  = Leaf (f a) 
      go (Node xl xr) = Node (go xl) (go xr) 

在第一个例子中,我使用go排序为maptree f宏。在第二个例子中,我采取的一个事实,即maptree的输入f处于go函数内部范围,因为go在的maptree一个where子句中声明的优势。

8

你缺少的递归调用maptree功能:

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree xl) (maptree xr) 

应该

maptree f (Leaf a)= Leaf (f a) 
maptree f (Node xl xr) = Node (maptree f xl) (maptree f xr) 
5

错误消息主要是告诉你什么是错的:你不及格maptree足够的参数。定义maptree f (Node xl xr)maptree需要两个参数,一个函数和一个树。但是当你称它为maptree xl时,你只给它一个参数(一棵树)。

在你的第二个版本中,你定义了maptree只带一个参数(一棵树),这就是为什么它不会产生这个错误。

您可以通过调用maptree f xl而不是maptree xl来解决您的问题。

8

请注意,对于Tree类型,这是Functor实例的明显fmap。因此,您可以使用DeriveFunctor扩展名让GHC为您生成。

{-# LANGUAGE DeriveFunctor #-} 
data Tree a = Leaf a | Node (Tree a) (Tree a) 
    deriving (Functor, Show) 

让我们试试吧。

*Main> fmap (+1) (Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)) 
Node (Node (Leaf 2) (Leaf 3)) (Leaf 4)