【发布时间】:2014-02-27 08:43:15
【问题描述】:
我有这个非常简单的功能
import qualified Data.ByteString.Lazy as B
getJson :: IO B.ByteString
getJson = B.readFile jsonFile
readJFile :: IO (Maybe Response)
readJFile = parsing >>= (\d ->
case d of
Left err -> return Nothing
Right ps -> return (Just ps))
where parsing = fmap eitherDecode getJson :: IO (Either String Response)
jsonFile 是我硬盘驱动器上文件的路径(请原谅缺少 do-notation,但我发现这样使用起来更清晰)
我的问题是;有没有办法让我放弃IO 部分,以便我可以单独使用字节串?
我知道您可以对某些 monad(例如 Either 和 Maybe)进行模式匹配以获取它们的值,但是您可以使用 IO 做类似的事情吗?
或者说不同的声音:有没有办法让readJFile 在没有 IO 的情况下返回 Maybe Response?
【问题讨论】:
-
我不是在谈论内置的东西,我只是在寻求一种方法来做到这一点,我也许可以构建自己;我的代码现在看起来的样子,我必须通过 5 个函数将那个 IO monad 拖到我身边,公平地说,它把它弄乱了很多,特别是考虑到我只在那个 ONE 函数中执行 IO 操作而没有其他地方
-
你永远不需要通过任何函数“拖动一个 monad”,除非它们都需要实际执行 IO。只需使用
fmap(或liftM/liftM2/ ...)将整个链提升到monad。 -
@ElectricCoffee 如果其他函数不做 IO,那么它们不应该在 IO 中。使它们依赖于字节串(即
B.ByteString -> ...类型),然后使用单个 IO 操作将读取与处理结合起来。 -
没有。
readJFile做 IO,所以它必须有一个 IO 类型。但是你可以把它抽象到字节串上,就像我上面说的那样。
标签: haskell io monads io-monad