
Hey everybody
I've been playing around with Parsec a little bit lately. I like it a
lot, but now I've hit a bit of a challenge. Suppose I have to parse a
variable length string representing a time interval. Depending on how
many fields there are, the time is either interpreted as seconds,
minutes and seconds or hours, minutes and seconds.
For example:
"... 31 ..." would be parsed as 31 seconds.
"... 05:31 ..." would be parsed as 5 minutes and 31 seconds.
"... 01:05:31 ..." would be parsed as 1 hour, 5 minutes and 31 seconds.
I've come up with the following solution using optionMaybe to deal with
the problem:
data ElapsedTime = ElapsedTime {
hours :: Int,
minutes :: Int,
seconds :: Int
} deriving (Show, Eq, Ord)
p_elapsed_time :: CharParser () ElapsedTime
p_elapsed_time = toElapsedTime <$> (optionMaybe p_Int)
<*> (optionMaybe (char ':' *> p_Int))
<*> (optionMaybe (char ':' *> p_Int <*
skipSpaces))
where toElapsedTime Nothing Nothing Nothing = ElapsedTime 0 0 0
toElapsedTime (Just s) Nothing Nothing = ElapsedTime 0 0 s
toElapsedTime (Just m) (Just s) Nothing = ElapsedTime 0 m s
toElapsedTime (Just h) (Just m) (Just s) = ElapsedTime h m s
Where p_Int simply parses a sequence of digits as an Int and skipSpaces
does just that.
This works correctly, but it also feels kinda clumsy. For one the
compiler rightly complains about nonexhaustive pattern matches in the
definition of the toElapsedTime function, although I believe that's
negligible in that particular case.
Is there a better i.e. more elegant way to tackle such a problem?
regards,
david
_______________________________________________
HaskellCafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskellcafe

