Search code examples
haskellpattern-matchingcase-statement

Haskell - Pattern matching in Case Of "Couldn't match expected type"


I have a custom datatype similar to:

data Token = Number Int
           | Otherthings

I want to be able to use the "Number" in one way and other things in another. So I can successfully create a case statement like:

parse x = case x of
    Number y -> y

Which then successfully takes:

let x = Number 7 in parse x

And evaluates to 7. However, when I try to change the "parse" function to be:

parse [] = []
parse (x:xs) = case x of
    Number y -> y

I get the error:

Couldn't match expected type `[a0]' with actual type `Int'
In the expression: y
In a case alternative: Number y -> y
In the expression: case x of { Number y -> y }

Why doesn't this work this way and what's the proper way to approach this problem? Thank you much!


Solution

  • Look at the types of the two parts of parse's definition separately.

    parse :: [a] -> [b] -- both the []'s are lists of some (possibly different) type
    parse [] = []
    

    and

    parse :: [Token] -> Int -- y, the function's return value, is an Int.
    parse (x:xs) = case x of
        Number y -> y
    

    and you can see that while a ~ Token works just fine, [b] ~ Int doesn't work: an Int is not a list of something. (The error message is using a0 where I'm using b.)

    The way out of this is to think about what type you want parse to return, and make sure all the parts of its definition match it. I'm not sure exactly what you want parse to do, so I can't give a definite answer there.