Haskell has the function parseTimeM
, which replaces the deprecated parseTime
function. I suppose the reason why the former is preferred over the latter is because it has better flexibility in reporting parse errors. Instead of a Maybe
, it can call fail
on the enclosing monad.
So I tried it. First, the deprecated function:
> parseTime defaultTimeLocale "%Y" "2015" :: Maybe UTCTime
Just 2015-01-01 00:00:00 UTC
> parseTime defaultTimeLocale "%Y" "201x" :: Maybe UTCTime
Nothing
Great. As expected. Then, the Identity
monad:
> runIdentity $ parseTimeM False defaultTimeLocale "%Y" "2015" :: UTCTime
2015-01-01 00:00:00 UTC
> runIdentity $ parseTimeM False defaultTimeLocale "%Y" "201x" :: UTCTime
*** Exception: parseTimeM: no parse of "201x"
Also expected, since the Identity
monad doesn't have an elegant failure mode. But, I expected something different with the Except
monad, the purpose of which is to gracefully catch errors.
> runExcept $ parseTimeM False defaultTimeLocale "%Y" "2015" :: Either () UTCTime
Right 2015-01-01 00:00:00 UTC
> runExcept $ parseTimeM False defaultTimeLocale "%Y" "201x" :: Either () UTCTime
*** Exception: parseTimeM: no parse of "201y"
Why is the exception being thrown here? Shouldn't it return Left ()
? How do I parse a time like I think it should, which is to gracefully return an error if the string to be parsed is poorly formatted?
Except
is part of the mtl
, which is a monad transformer library. The usual style with transformers is to define the transformer for some behavior (ExceptT
in this case) and express the base version as a type synonym:
type Except e = ExceptT e Identity
So you are probably getting an exception because the fail
for Except
has to go through the Identity
monad at the bottom of its little monad transformer stack.
With Except e
specifically, how would you implement fail
for an arbitrary type e
? Since we don't know anything at all about e
, we can't just conjure up a value of e
given a string, so fail
would have to give you an exception or loop forever.
All this is a pretty good argument against the parseTimeM
style of relying on fail
in the Monad
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With