parsing - 如何正确使用Haskell的 `parseTimeM`函数?

标签 parsing haskell time

Haskell 具有函数 parseTimeM ,它取代了已弃用的 parseTime 函数。我想前者比后者更受欢迎的原因是它在报告解析错误方面具有更好的灵 active 。它可以在封闭的 monad 上调用 fail,而不是 Maybe

所以我尝试了一下。首先,已弃用的函数:

> 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 () 吗?如何像我想象的那样解析时间,即如果要解析的字符串格式不正确,则优雅地返回错误?

最佳答案

Exceptmtl 的一部分,它是一个 monad 转换器库。转换器的常见风格是为某些行为定义转换器(在本例中为 ExceptT),并将基本版本表示为类型同义词:

type Except e = ExceptT e Identity

所以你可能会遇到异常,因为 Exceptfail 必须经过其小 monad 底部的 Identity monad变压器堆栈。

具体而言,对于Except e,您如何为任意类型e实现fail?由于我们对 e 一无所知,因此我们不能仅根据给定的字符串想象出 e 的值,因此 fail 必须给你一个异常或永远循环。

所有这些都是一个很好的论据,反对依赖 Monad 类中的 failparseTimeM 风格。

关于parsing - 如何正确使用Haskell的 `parseTimeM`函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114318/

相关文章:

html - 如何使用维基百科的API仅抓取模板:Infobox Automobile

java - 使用jsoup解析html表

haskell - 如何使用免费的 monad 实现 Reader?

java - 时间格式问题

c - 我是否需要释放 localtime() 函数返回的指针?

java - 是否有 GSP(通用 SQL 解析器)的替代品?

regex - 解析 ps 的 "etime"输出并将其转换为秒

haskell - 无法写入句柄

haskell - 负零的绝对值 - bug,还是浮点标准的一部分?

sqlite - SQLite时间范围过滤器?