我试图在挑选中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.快速失败通常是令人垂涎的财产.
我应该四处走动并read用readIOs 代替所有s吗?
不,readIO是邪恶的.喜欢read它应该被认为是部分功能.read如果确保解析失败永远不会发生,或者你只是检查GHCi中的一些东西,那么(或多或少)是好的.
如果你想要抓住解析失败,那就明确地说明一下,不要只是把它IO当作monad.reads是一个简单的选项,对于更高级的东西,使用像parsec这样的完整解析库.