Is it possible to nest guards in Haskell?
No, but you can use cases if you'd like:
parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
| isDigit h =
case () of
() | p == Nothing -> Just([h], ls)
| otherwise -> Just (h:fst d, snd d) -- Ends in a digit
| h == '.' =
case () of
() | p == Nothing -> Nothing
| not ('.' `elem` (snd d)) -> Just (h:(fst d), snd d)
| otherwise = Nothing
where
p = parseNumber ls
Just d = parseNumber ls
Alternatively, multiway if works in a similar manner (if True | p1 -> b ; | p2 -> c
).
Recent GHC now has MultiWayIf
:
{-# LANGUAGE MultiWayIf #-}
parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
| isDigit h = if
| p == Nothing -> Just ([h], ls)
| otherwise -> Just (h:fst d, snd d)
| h == '.' = if
| p == Nothing -> Nothing
| not ('.' `elem` (snd d)) -> Just (h:(fst d), snd d)
| otherwise = Nothing
where p@(~(Just d)) = parseNumber ls
But this is better written slightly differently anyhow, without the partiality.
{-# LANGUAGE MultiWayIf #-}
parseNumber :: String -> Maybe (String, String)
parseNumber [] = Just ("", "")
parseNumber (h:ls)
| isDigit h = if
| Nothing <- p -> Just ([h], ls) -- PatternGuards, on by default
| Just d <- p -> Just (h:fst d, snd d)
| h == '.' = if
| Nothing <- p -> Nothing
| Just d <- p, not ('.' `elem` snd d) -> Just (h:(fst d), snd d)
| otherwise = Nothing
where p = parseNumber ls
and you may as well use maybe
.
parseNumber :: String -> Maybe (String, String)
parseNumber "" = Just ("", "")
parseNumber (h:hs)
| isDigit h = maybe (Just ([h], hs)) (\(num, rest') -> Just (h:num, rest')) rest
| h == '.' = maybe Nothing (\(num, rest') -> if '.' `elem` num then Nothing
else Just (h:num, rest')
) rest -- This logic is a bit wonky; it doesn't really work
| otherwise = Nothing
where rest = parseNumber hs
No, you can't. We all want it, but nobody can come up with a sensible syntax.