Athan Clark
Athan Clark

Reputation: 3970

Can't get type signature working for simple recursive function

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

Answers (2)

AndrewC
AndrewC

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

Niklas B.
Niklas B.

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 tests 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

Related Questions