Haskell具有函数parseTimeM
,它取代了已弃用的parseTime
函数。我认为前者优先于后者的原因是因为它在报告解析错误方面具有更好的灵活性。可以在封闭的monad上调用Maybe
而不是fail
。
所以我试了一下。首先,弃用的功能:
> parseTime defaultTimeLocale "%Y" "2015" :: Maybe UTCTime
Just 2015-01-01 00:00:00 UTC
> parseTime defaultTimeLocale "%Y" "201x" :: Maybe UTCTime
Nothing
大。正如所料。然后,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"
同样可以预料到,因为Identity
monad没有优雅的故障模式。但是,我期望与Except
monad有所不同,其目的是优雅地捕获错误。
> 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"
为什么要抛出异常?它不应该返回Left ()
吗?我如何解析我认为应该的时间,如果要解析的字符串格式不正确,那么优雅地返回错误?
答案 0 :(得分:3)
Except
是mtl
的一部分,它是monad变换器库。变换器的通常样式是为某些行为定义变换器(在本例中为ExceptT
)并将基本版本表示为类型同义词:
type Except e = ExceptT e Identity
所以你可能会遇到异常,因为fail
的{{1}}必须通过其小monad变换器堆栈底部的Except
monad。
具体针对Identity
,您如何为任意类型Except e
实施fail
?由于我们对e
一无所知,因此我们不能在给定字符串的情况下设想e
的值,因此e
会拥有给你一个例外或永远循环。
所有这些都是针对fail
类中依赖parseTimeM
的{{1}}风格的一个很好的论据。