Haskell function pattern-matching issues

Tag: haskell Author: zyyzyyzyy8810221122 Date: 2009-08-16

I'm doing some homework and while I have some experience with SML, Haskell has some oddities. Consider this simple function:

type Pos = (Int, Int)
data Move = North | South | East | West
move :: Move -> Pos -> Pos
move North (x,y) = (x, y+1)
move South (x,y) = (x, y-1)
move East  (x,y) = (x+1, y)
move West  (x,y) = (x-1, y)

moves :: [Move] -> Pos -> Pos
moves (m:ms) (x,y) = moves ms (move m (x,y))
moves [] p = p

This code works. However, if I swap out the (x,y) tuple (which I dont use anyway) with a simple p it fails on invocation (the declaration works fine of course):

moves :: [Move] -> Pos -> Pos
moves (m:ms) p = moves ms (move m p)
moves [] p = p

*Main> let p = (1,1) :: Pos
*Main> move [North, North] p

<interactive>:1:5:
    Couldn't match expected type `Move' against inferred type `[a]'
    In the first argument of `move', namely `[North, North]'
    In the expression: move [North, North] p
    In the definition of `it': it = move [North, North] p

Which seems strange to me, as the second parameter is already typed as a Pos in the definition, so how come this chokes, and only on invocation? I'm using ghci btw.

You spelled "moves" as "move".

Best Answer

You did forget an "s" at the end of move**s** call, didn't you?

*Main> move [North, North] p

comments:

Yes, he did. He passed move something of type [a], when it was expecting `Move'. And amazingly, that's exactly what the error message says.
Bah... >_>