2013-04-23 113 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