前奏的类型是否有很好的理由?读
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
是标识(对于作为Show
和Read
实例的类型),show . read
是show
(即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)