什么时候我更喜欢读取读取?(或相反亦然)

ber*_*rio 1 haskell

我试图在挑选中readIO进行权衡read,然后我写了这2个片段

> map read . words <$> getLine :: IO [Int]
1 2 a
[1,2,*** Exception: Prelude.read: no parse
> mapM readIO . words =<< getLine :: IO [Int]
1 2 a
*** Exception: user error (Prelude.readIO: no parse)
Run Code Online (Sandbox Code Playgroud)

我知道在纯代码中抛出异常(就像read那样)通常很糟糕,但通常我总是在IO monad中使用read,因此我应该能够几乎总是捕获异常.

readIO是不是在为许多片断/例子/教程使用从我所看到的,但OTOH在携带型的可能性的错误似乎是一件好事,并收集所有Read a在一个单一的IO mapM产量更早的误差比第一简单的例子map.快速失败通常是令人垂涎的财产.

我应该四处走动并readreadIOs 代替所有s吗?

lef*_*out 5

不,readIO是邪恶的.喜欢read它应该被认为是部分功能.read如果确保解析失败永远不会发生,或者你只是检查GHCi中的一些东西,那么(或多或少)是好的.

如果你想要抓住解析失败,那就明确说明一下,不要只是把它IO当作monad.reads是一个简单的选项,对于更高级的东西,使用像parsec这样的完整解析库.

  • 甚至@berdario,导入Text.Read并使用readMaybe或只使用读取.它们允许您纯粹使用标准库来处理失败的解析.即使对于练习代码,也总是更好地处理错误.养成这种习惯是值得的. (3认同)
  • 因为它与IO无关的滥用错误处理的"IO".如果通过事先确保解析成功来防止错误发生,那就没关系了; 但是你不妨使用`read`而不需要随身携带`IO` monad. (2认同)