gpt4 book ai didi

haskell - 单子(monad)转换器上下文中的单子(monad)

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

我很难捕获 monad 和 monad 转换器。我有
以下人为示例(不可编译):

import Control.Monad
import Control.Monad.Error
import Control.Monad.Reader

data State = State Int Int Int
type Foo = ReaderT State IO

readEither :: String -> Either String Int
readEither s = let p = reads s
in case p of
[] -> throwError "Could not parse"
[(a, _)] -> return a

readEitherT :: IO (Either String Int)
readEitherT = let p s = reads s
in runErrorT $ do
l <- liftIO (getLine)
readEither l

foo :: Foo Int
foo = do
d <- liftIO $ readEitherT
case d of
Right dd -> return dd
Left em -> do
liftIO $ putStrLn em
return (-1)

bar :: Foo String
bar = do
liftIO $ getLine

defaultS = State 0 0 0

如果我将 readEither 的功能复制到 readEitherT,它可以工作,但我
有一种唠叨的感觉,我可以利用现有的力量
readEither 函数,但我不知道如何。如果我尝试抬起
在 readEitherT 函数中的 readEither,它将它提升到 ErrorT String IO
(Either String Int)
正如它应该。但我应该以某种方式将它发送到 ErrorT
String IO Int
.

如果我走错了方向,那么正确的方法是什么
处理需要 IO(或其他 monads)并且将从中调用的错误
一元上下文(见示例中的 foo 函数)

编辑:
显然我不清楚我想做什么。也许以下函数描述了我想知道的内容和原因
maybePulseQuit :: Handle -> IO (Either String ())
maybePulseQuit h = runErrorT $ do
f <- liftIO $ (communicate h "finished" :: IO (Either String Bool))
(ErrorT . pure) f >>= \b → liftIO $ when b $ liftIO pulseQuit

这可行,但由于绑定(bind)仍然很难看。这比以前的有大小写检查的版本要清楚得多。这是推荐的方法吗?

最佳答案

不清楚为什么需要 ErrorT .你可以实现readEitherT

readEitherT :: IO (Either String Int)
readEitherT = fmap readEither getLine

如果你真的需要 ErrorT出于某种原因,您可以创建实用函数 eitherToErrorT :
eitherToErrorT = ErrorT . pure

readEitherT = runErrorT $ do
l <- liftIO $ getLine
eitherToErrorT $ readEither l

[添加]
也许您只想添加 ErrorT进入你的单子(monad)堆栈......
data State = State Int Int Int
type Foo = ErrorT String (ReaderT State IO)

runFoo :: Foo a -> State -> IO (Either String a)
runFoo foo s = runReaderT (runErrorT foo) s

doIt :: Int -> Foo Int
doIt i = if i < 0
then throwError "i < 0"
else return (i * 2)

例子:
*Main> runFoo (doIt 1 >>= doIt) (State 0 0 0)
Right 4
*Main> runFoo (doIt (-1) >>= doIt) (State 0 0 0)
Left "i < 0"

关于haskell - 单子(monad)转换器上下文中的单子(monad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4192056/

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