为什么 Haskell 的前奏曲,不读回一个“也许”?

为什么 Prelude.read 的类型是

read :: Read a => String -> a

而不是返回 Maybe值?

read :: Read a => String -> Maybe a

Since the string might fail to be parseable Haskell, wouldn't the latter be be more natural?

或者甚至是一个 Either String a,如果它不解析,Left将包含原始字符串,如果它解析,Right将包含结果?

编辑:

我不是想让别人为我写一个相应的包装。只是想确保这样做是安全的。

15656 次浏览

编辑 : 从 GHC 7.6开始,基础软件包中的 Text.Read模块提供了 readMaybe,以及 readEither://href = “ http://hackage.haskell.org/package/archive/base/update/doc/html/Text-Read.html # v: readmaybe”rel = “ noReferrer”> http://hackage.haskell.org/packages/archive/base/latest/doc/html/text-read.html#v:readmaybe


好问题!阅读的类型本身不会很快改变,因为那会破坏很多东西。但是,应该有一个 maybeRead函数。

为什么没有? 答案是“惯性”。有一个 08年的讨论因为讨论“失败”而脱轨

好消息是,人们已经充分相信要开始从图书馆的失败中走出来。坏消息是提案在混乱中迷失了方向。应该就是这样一个函数,虽然它很容易编写(而且在许多代码库中有无数非常相似的版本)。

See also 这个讨论.

个人而言,我使用的是 安全包裹的版本。

是的,如果有一个返回“也许”的 read 函数,它会很方便。你可以自己做一个:

readMaybe :: (Read a) => String -> Maybe a
readMaybe s = case reads s of
[(x, "")] -> Just x
_ -> Nothing

除了惯性和/或改变洞察力之外,另一个原因可能是,拥有一个可以作为 show的倒数的函数在美学上是令人愉快的。也就是说,您希望 read . show是标识(对于 ShowRead的实例类型) ,而 show . readshow范围内的标识(即 show . read . show == show)

read类型的 Maybe打破了与 show :: a -> String的对称性。

正如@augustss 指出的,您可以创建自己的安全读取函数。但是,他的 readMaybe并不完全与 read 一致,因为它并不忽略字符串末尾的空格。(我犯过一次这样的错误,我不太记得上下文了)

看看 definition of read in the Haskell 98 report,我们可以修改它来实现一个与 read完全一致的 readMaybe,这并不太不方便,因为它所依赖的所有函数都在序曲中定义:

readMaybe        :: (Read a) => String -> Maybe a
readMaybe s      =  case [x | (x,t) <- reads s, ("","") <- lex t] of
[x] -> Just x
_   -> Nothing

这个函数(称为 readMaybe)现在处于 Haskell 前奏曲中! (从当前的基数——4.6开始)