Haskell 如何将多个单子效果组合到同一do块中?
我有一个函数,它调用类型为Haskell 如何将多个单子效果组合到同一do块中?,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,我有一个函数,它调用类型为IO的函数和类型为的函数,要么调用字符串a 我想将do符号中的效果组合起来,以便在必要时解包IO,同时在我遇到的第一个左侧处中止计算 这里有一个非常简单的例子,你能帮我修复它吗?(使用runEitherT是可选的。但我认为如果使用plain,您将无法使用MonadError和MonadIO功能) entryPoint::IO(字符串或Int) 入口点=runEitherT foo --p和p'的类型应为Int, --而errorf会迫使计算中止(与throwError一
IO
的函数和类型为的函数,要么调用字符串a
我想将do符号中的效果组合起来,以便在必要时解包IO
,同时在我遇到的第一个左侧
处中止计算
这里有一个非常简单的例子,你能帮我修复它吗?(使用runEitherT是可选的。但我认为如果使用plain,您将无法使用MonadError
和MonadIO
功能)
entryPoint::IO(字符串或Int)
入口点=runEitherT foo
--p和p'的类型应为Int,
--而errorf会迫使计算中止(与throwError一样)
foo::EitherT字符串IO Int
foo=do
p或字符串b
errorf=未定义
iof::a->IO a
iof=未定义
零件
p' <- return $ errorf p
其中,上面的返回
构建了一个IO
操作。这不是我们想要的——这里有一个额外的右边的。相反,我们想要
p' <- EitherT (return (Left something))
p'p'我不明白你为什么要使用EitherT
然后抛出undefined
about。这看起来很奇怪。你到底想完成什么?名称entryPoint
和foo
不是那么具有描述性。因为实现并不重要,只要您知道一个方法不执行IO,另一个方法使用其中一个来报告错误。我非常确定字符串IO Int是我需要的行为的正确类型,所以我只需要代码typecheck@chi它编译好了,谢谢。所以基本上return$errorf p'
已经有了抽象意义上的正确类型,但我不得不将其进一步打包到EitherT
中,以满足类型检查器的要求。原始的return$x
位于EitherT s IO
中,表示成功,建模为EitherT(return(Right x))
,后者return
生成IO
。因此,原始代码构建了EtiherT(return(Right(Left…))
,因为x=Left..
这是错误的。相反,我们使用EitherT$return$errorf p
来生成IO
(而不是EitherT…
),因此我们得到EitherT(return(Left…)
)。这很奇怪,因为我们似乎在进一步打包它,而我们没有:添加EitherT
使Haskell选择一个不同的返回
(在IO
中,而不是EitherT
)!为什么要将Control.Monad.Error.Class中的throwError更改为left?它是用throwError编译的,我觉得这个名字更能体现语义。@BruceBerry我对throwError的看法是错误的,IO
——我以为有人在引发异常,但事实并非如此。
p' <- EitherT (return (Right (Left something)))
p' <- EitherT (return (Left something))
p' <- EitherT $ return $ errorf p