Reputation: 3970
Here is my code:
test :: (Num a) => [a] -> a
test [] = 0
test [x:xs] = x + test xs
Yet when I run it through ghci as :l test
, I get this error:
[1 of 1] Compiling Main ( test.hs, interpreted )
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.
Try not to laugh :) it's my first attempt at haskell. Any help or explanations would be awesome.
PS: I know this could be easily done with a fold, but I'm trying to practice writing my own type signatures. Thanks in advance!!
Upvotes: 5
Views: 249
Reputation: 32455
You mean
test :: (Num a) => [a] -> a
test [] = 0
test (x:xs) = x + test xs -- note round brackets
with round brackets.
[x:xs]
is a list with one element, itself a list, whereas (x:xs)
is a list with a first element x
and tail xs
.
If you type length (1:[1,1,1])
you'll get 4, but if you type length [1:[1,1,1]]
you'll get 1 - the only element is a list.
Upvotes: 8
Reputation: 95278
You probably meant to match the list as a whole, not the first element of the list:
test (x:xs) = ...
If you do otherwise, the pattern has the inferred type [[b]]
, so a == [b]
according to test
s signature, so xs
must have type [b]
, so test xs
must have type b
but also type a
according to the signature of test
, which would mean that a == [a]
, which is a contradiction and leads to the unification error :)
Upvotes: 5