2011-10-02 102 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)