5

这是我的代码:

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

然而,当我通过 ghci as 运行它时:l test,我得到了这个错误:

[1 of 1] 编译 Main(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.

尽量不要笑:) 这是我第一次尝试haskell。任何帮助或解释都会很棒。

PS:我知道这可以通过折叠轻松完成,但我正在尝试练习编写自己的类型签名。提前致谢!!

4

2 回答 2

8

你的意思是

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

带圆括号。

[x:xs]是一个包含一个元素的列表,它本身就是一个列表,而(x:xs)是一个包含第一个元素x和 tail的列表xs

如果你输入length (1:[1,1,1]),你会得到 4,但如果你输入length [1:[1,1,1]],你会得到 1——唯一的元素是一个列表。

于 2013-04-23T21:25:16.830 回答
5

您可能打算将列表作为一个整体进行匹配,而不是列表的第一个元素:

test (x:xs) = ...

如果不这样做,则模式具有推断的类型[[b]],因此a == [b]根据tests 签名,因此xs必须具有类型[b],因此test xs必须具有类型,b而且a根据 的签名也有类型test,这意味着a == [a],这是一个矛盾并导致统一错误 :)

于 2013-04-23T21:25:45.377 回答