1
votes

I'm new to functional programming and haskell, so I'm just starting out learning both by attempting some Euler problems. This involves a great deal of list summations.

So I'm trying to write a recursive list summation function that takes one list as input and returns an integer as output, for instance:

-- Sum up a list
listsum :: [int] -> int
listsum [a:b:[]] = a + b
listsum x = head x + listsum tail x

When compiling this code, I receive this error:

Couldn't match expected type `[[int] -> int]'
            with actual type `[a0] -> [a0]'
Relevant bindings include
  x :: [int]
    (bound at C:\Users\Rade\Documents\GitHub\haskell\euler_2.hs:15:9)
  listsum :: [int] -> int
    (bound at C:\Users\Rade\Documents\GitHub\haskell\euler_2.hs:14:1)
Probable cause: `tail' is applied to too few arguments
In the first argument of `listsum', namely `tail'
In the second argument of `(+)', namely `listsum tail x'

I've tried to research the pattern matching, but I cannot understand what it means with expected type versus actual type. Where am I going wrong?

1

1 Answers

5
votes
listsum [a:b:[]] = a + b

Here, a:b:[] means the list [a, b], so [a:b:[]] means [[a, b]], which is not what you want.

Simply change this to

listsum (a:b:[]) = a + b

Now, in

listsum x = head x + listsum tail x

the part listsum tail x means apply listsum to tail, and then apply the result to x. I suppose you meant apply tail to x and then apply listsum to the result, which can be expressed as listsum (tail x).


I suggest a bit cleaner implementation, which assumes that summing empty list yields zero.

listsum [] = 0
listsum (x:t) = x + listsum t

This differs in functionality from your implementation, since it handles lists with zero or one element correctly.