我的印象是,由于错误原因,你重新尝试使用<代码>MonadError。
在<代码>(many1 parser1) <> parser<2>/code>中,你为避免使用<代码><<>/code>和<>;
——如果你不喜欢,使用不同的组合器。 或许像(many1 parser1)”和“>”; parser2
(many1 parser1);你当然可以使用>>=
(many1 parser1)的结果与parser2
的结果合并。)
(说明:在此点之后,目前问题没有真正的好解决办法,只是某些事情为什么会赢得工作......。 希望这可能是(有些是)开明的,但并不期望太多。
更仔细地审查ParsecT / MonadError之间的互动。 我担心它会带来一点点迷惑,我仍不敢真正地确定如何最好地去做被占领土上想要做的事情,但我希望以下一点至少能说明原办法未能取得成功的原因。
首先,请注意it 不能说Parsec是Monad Error的一个实例。 假释是ParsecT在 in门身份时制作的mon; 只有当获得内mon时,ParsecT才会产生蒙德埃尔的事例,而这本身就是莫德埃洛尔与他合作的一个实例。 GHCi互动的相关碎片:
> :i Parsec
type Parsec s u = ParsecT s u Identity
-- Defined in Text.Parsec.Prim
-- no MonadError instance
instance (MonadError e m) => MonadError e (ParsecT s u m)
-- Defined in Text.Parsec.Prim
-- this explains why the above is the case
-- (a ParsecT-created monad will only become an instance of MonadError through
-- this instance, unless of course the user provides a custom declaration)
其次,let自称是捕获量的一个工作榜样。 Error and ParsecT。 考虑全球卫生联合会的这一互动:
> (runParserT (char a >> throwError "some error") () "asdf" "a" :: Either String (Either ParseError Char)) `catchError` (e -> Right . Right $ z )
Right (Right z )
这种说明似乎是必要的(这似乎对我来说是直觉的,但与原始问题毫不相关,因此,我赢得了尝试。 整个表达方式由格奥尔蒂斯确定如下:
Either String (Either ParseError Char)
因此,我们定期取得以下成果:<条码>。 Either String monad in place otherwise Identity
monad. 由于<代码>Either String 是Monad Error
的一个实例,我们可以使用<代码>throwError / submissionsError
,但发送到liver Error
的投稿人当然必须产生正确的数值。 这对打破司空见惯的例行公事——恐怕。
<>Back to example Code from the question. 这略有不同。 请审查问题定义的<代码>ret的类型:
forall (m :: * -> *) a.
(Monad m) =>
m (Either [Char] (Either ParseError a))
(根据GHCi......指出,我不得不取消独一无二的限制,其编号为{-# LANGUAGE No Mono吗?”
这种类型与<代码>ret做一些事情的可能性有关。 在这方面,我们:
> runParserT ret () "asdf" "a"
Right (Left "some error")
中文无需改动。 恐怕我看不出如何把这 into为有助于打破教区进程的东西。