5

我想让我的 monad 转换器成为一个实例,MonadError如果转换后的 monad 是一个实例。基本上我希望我的变压器表现得像内置变压器一样,例如有一个MonadError实例StateT

MonadError e m => MonadError e (StateT s m)

我试过这样做:

instance MonadError e m => MonadError e (MyMonadT m)

但是 GHC 开始抱怨 undecidable 实例,显然 MTL 库只是启用了 undecidable 实例,但是有什么办法可以避免这种情况呢?还是在这种情况下没问题,不会造成任何问题?

4

1 回答 1

8

这基本没问题。UndecidableInstances不是那么可怕;这意味着编译器可以进入无限循环,而不是找到一个实例。这听起来很糟糕,直到您意识到 GHC 实际上对查找实例所需的步骤数有限制;除非你写了一个糟糕的实例,否则什么都不会出错,而且你得到的错误消息通常会很明显地表明出了什么问题。1OverlappingInstances当然,它远没有像(或更糟,IncoherentInstances)之类的东西那么可怕。

它抱怨的原因是因为对toMonadError有功能依赖。这意味着选择决定了必须是什么;即 each只与一个相关联。对此(覆盖条件)的检查是保守的,因此很容易遇到这样的问题,您可以尝试“递归降低一个级别”来指定.mememee

1它会列出它查看的所有实例以尝试找到它正在寻找的实例,因此您会看到一堆重复的行。但通常你一开始就不会遇到这样的麻烦。

于 2012-03-30T23:02:03.590 回答