2013-04-23 60 views
5

在這裏工作是我的代碼:無法獲取類型簽名簡單的遞歸函數

test :: (Num a) => [a] -> a 
test []  = 0 
test [x:xs] = x + test xs 

然而,當我運行它通過ghci中爲:l test,我得到這個錯誤:

[1 1]編譯主要(test.hs,解釋)

test.hs:3:7: 
    Couldn't match type `a' with `[a]' 
     `a' is a rigid type variable bound by 
      the type signature for spew :: Num a => [a] -> a at test.hs:2:1 
    In the pattern: x : xs 
    In the pattern: [x : xs] 
    In an equation for `spew': spew [x : xs] = x + spew xs 
Failed, modules loaded: none. 

儘量不要笑:)這是我第一次嘗試在哈斯克爾。任何幫助或解釋都會很棒。 PS:我知道這可以通過摺疊很容易完成,但我正在嘗試寫我自己的類型簽名。提前致謝!!

回答

8

你的意思是

test :: (Num a) => [a] -> a 
test []  = 0 
test (x:xs) = x + test xs -- note round brackets 

圓形支架。

[x:xs]是一個元件,它本身的列表的列表,而(x:xs)是與第一元件x和尾xs列表。

如果輸入length (1:[1,1,1]),您將得到4,但如果您鍵入length [1:[1,1,1]],您將得到1 - 唯一的元素是一個列表。

+1

Gah !!我應該看到的!謝謝! – 2013-04-23 21:51:54

+0

@AnhanClark當我們學習Haskell時,我們都會經歷這種感覺。 – Dilawar 2013-04-23 23:36:53

5

你可能意味着將匹配列表作爲一個整體,而不是列表的第一個元素:根據test簽名

test (x:xs) = ... 

如果你不這樣做,該模式有推斷類型[[b]],所以a == [b] ,所以xs類型必須[b],所以test xs類型必須b也鍵入a根據test簽名,這將意味着a == [a],這是一個矛盾,並導致統一錯誤:)

+0

不好意思的人AndrewC的回答比較完整:)謝謝你,雖然!!! – 2013-04-23 21:51:06