这是我的代码:
test :: (Num a) => [a] -> a
test [] = 0
test [x:xs] = x + test xs
然而,当我通过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.
尽量不要笑:)这是我第一次尝试使用haskell。任何帮助或解释都会很棒。
PS:我知道这可以通过折叠轻松完成,但我正在尝试编写自己的类型签名。在此先感谢!!答案 0 :(得分: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 :(得分:5)
您可能希望将列表作为整体匹配,而不是列表的第一个元素:
test (x:xs) = ...
如果不这样做,则该模式具有推断类型[[b]]
,因此根据a == [b]
签名具有test
,因此xs
必须具有类型[b]
,因此test xs
必须有b
类型,但也要根据a
的签名键入test
,这意味着a == [a]
,这是一个矛盾和引导统一错误:)