gpt4 book ai didi

haskell - 一个 do-block 中的多个 monad

转载 作者:行者123 更新时间:2023-12-04 01:44:04 24 4
gpt4 key购买 nike

我目前正在尝试学习 Haskell,我真的无法理解在 do-block 中只使用一个单子(monad)的概念。如果我有 foo :: Int -> Maybe Int并想使用例如函数hIsEOF :: Handle -> IO Bool在这个函数中。有人可以用一些基本示例解释我如何使用hIsEOF并且可以以某种方式与 Bool 一起工作?

我一直在尝试在这里和谷歌上搜索,但我总是遇到一些高级的东西,基本上没有人解释如何,他们只是就如何将它适合到 OP 的代码中提供建议。我在那些线程中看到了 monad 转换器,但即使在阅读了一些资源之后,我似乎也无法找到正确的方法来使用它们。

最佳答案

使用 monad 转换器,您需要做的就是

  • Int -> Maybe Int 更改函数签名至
    foo :: Int -> MaybeT IO Int
  • lift do 中的所有 IO 操作 block (或 liftIO 在这种情况下)。见 here why you need this lifting and what exactly it does .
  • 使用 runMaybeT 运行函数

  • 一个最小的例子是:
    import Control.Monad.Trans (lift)
    import Control.Monad.Trans.Maybe (MaybeT, runMaybeT)

    import System.IO (openFile, hClose, hSeek, hIsEOF)
    import System.IO (IOMode(ReadMode), SeekMode(AbsoluteSeek))

    foo :: Int -> MaybeT IO Int
    foo i = do
    h <- lift $ openFile "test.txt" ReadMode
    -- move the handle i bytes ahead
    lift . hSeek h AbsoluteSeek $ fromIntegral i
    eof <- lift $ hIsEOF h -- check if hit end of file
    lift $ hClose h
    if eof then fail "eof!" else return i

    然后,
    \> runMaybeT $ foo 1
    Just 1
    \> runMaybeT $ foo 100 -- would hit eof
    Nothing

    您从中得到的将是以下类型:
    (runMaybeT . foo) :: Int -> IO (Maybe Int)

    关于haskell - 一个 do-block 中的多个 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35592415/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com