为什么 Haskell's Prelude.read 没有返回一个 Maybe?



前奏的类型是否有很好的理由?读

read :: Read a => String -> a

而不是返回Maybe值?

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

由于字符串可能无法被Haskell解析,后者不是更自然吗?

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

编辑:

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

Edit:从GHC 7.6开始,readMaybe在基本包中的Text.Read模块中可用,以及readEither: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Text-Read.html#v:readMaybe


好问题!读取类型本身不会很快改变,因为这会破坏很多东西。然而,应该是一个maybeRead函数。

为什么没有?答案是"惯性"。08年有一个讨论因为一个关于"失败"的讨论而偏离了轨道。"

好消息是人们已经被说服开始远离库中的失败。坏消息是这个提议在混乱中被淹没了。应该是这样一个函数,尽管它很容易编写(并且在许多代码库中有无数非常相似的版本)。

参见此讨论。

我个人使用安全包中的版本

是的,这将是方便的读取函数返回Maybe。你可以自己做一个:

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一致,因为它不会忽略字符串末尾的空白。(我犯过一次错误,我不太记得上下文了)

看看Haskell 98报告中read的定义,我们可以修改它来实现一个与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)

最新更新