I’m learning haskell and am currently trying to parse Integers and Floats from strings.
However, when trying my readNum function on “342” or any “number” that doesn’t have a single or more non-numeric characters ghci reports to me:
* Exception: parse.hs:125:18-46: Irrefutable pattern failed for pattern (i, (a
: as))
data Token
= IntTok Int | FloatTok Float | EOF
readNum :: String->(Token, String)
readNum [] = (EOF, [])
readNum xs = let (i, (a:as)) = span isDigit xs --This is line 125
in (case a of
('.') -> let (j, (b:c:bs)) = span isDigit as
in (if ((toLower b) == 'e' && (c == '+' || c == '-' || (isDigit c)))
then (let (k, d) = span isDigit bs in (FloatTok (read (concat [i,[a],j, [b],[c],k])::Float), d))
else (FloatTok (read (concat [i,[a],j])::Float), (b:c:bs)))
_ -> (IntTok (read i::Int), (a:as)))
Is there a better way to handle the case when span isDigit xs returns an empty list as the second element of the tuple?
-Thanks
You’re getting the error because if you use a simple Integer like
"342"thenspan isDigit "342"is just("342",[]), which can’t match(l,a:as). A pattern that is supposed to always match is called an irrefutable pattern. As you’ve found out, patterns in let bindings are irrefutable, so…You need to to stick to patterns that will always match in a let binding. For example you could do
I gave a silly error message, but clearly you should write more sensible code there.