Haskell newbie here, trying to write code to parse math expressions. Code:
isDigit :: Char -> Bool
isDigit c = c >= '0' && c <= '9'
parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
| isDigit h
| p == Nothing = Just([h], ls) -- Digit found <<< ERROR!!
| otherwise = Just (h:fst d, snd d) -- Ends in a digit
| h == '.'
| p == Nothing = Nothing -- Ends in a point
| not ('.' `elem` (snd d)) = Just (h:(fst d), snd d) -- We don't want multiple dots
| otherwise = Nothing -- Not a number, stop looking!
where
p = parseNumber ls
Just d = parseNumber ls -- Float version of p. Not used if p is Nothing
This function is supposed to take a string that starts with a number, and returns the number separated from the rest of the expression. Example:
parseNumber "123.0 + 2"
("123.0", " + 2")
I think this nested guards' syntax reads really nicely, but it doesn't work. The error reads, for the marked line:
parse error on input `|'
Are chained guards not allowed in Haskell? Or am I writting this wrongly somehow? Also, what alternatives do I have to chain logic in a simple way?
It is possible to chain guards, with
,
. This does basically the same as&&
in fjarri's answer, but is more versatile when it comes to pattern guards.What's not possible is nesting guards. Well, in your example that's only actually needed in the first clause. You could write
No, it's not possible. Why not just write it linearly as
If your guards become too involved it's probably a sign that you need to extract a function.