无法为简单的递归函数获取类型签名

Ath*_*ark 5 recursion haskell

这是我的代码:

test :: (Num a) => [a] -> a
test []     = 0
test [x:xs] = x + test xs
Run Code Online (Sandbox Code Playgroud)

然而,当我通过ghci运行它时:l test,我收到此错误:

[1/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.
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*ewC 8

你的意思是

test :: (Num a) => [a] -> a
test []     = 0
test (x:xs) = x + test xs -- note round brackets
Run Code Online (Sandbox Code Playgroud)

带圆括号.

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

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


Nik*_* B. 5

您可能希望将列表作为整体匹配,而不是列表的第一个元素:

test (x:xs) = ...
Run Code Online (Sandbox Code Playgroud)

如果你不这样做,模式有推断类型[[b]],所以a == [b]根据tests签名,所以xs必须有类型[b],所以test xs必须有类型,b但也要a根据签名类型test,这意味着a == [a],这是一个矛盾,导致统一错误:)