Mar*_*ota 5 haskell monad-transformers
我想让我的monad变换器成为MonadError转换后的monad是一个实例的实例.基本上我希望我的变压器能像内置变换器一样工作,例如有一个MonadError实例StateT:
MonadError e m => MonadError e (StateT s m)
Run Code Online (Sandbox Code Playgroud)
我试过这样做:
instance MonadError e m => MonadError e (MyMonadT m)
Run Code Online (Sandbox Code Playgroud)
但是GHC开始抱怨不可判断的实例,显然MTL库只是启用了不可判定的实例,但是有什么方法可以避免这种情况吗?或者在这种情况下可以,它不会导致任何问题?
这基本上没问题.UndecidableInstances并不是那么可怕; 这意味着编译器可以进入无限循环而不是查找实例.这听起来很糟糕,直到你意识到GHC实际上对查找实例所需的步骤数量有限制; 除非你编写一个不好的实例,否则什么都不会出错,而你得到的错误消息通常会使错误显而易见.1当然,它比那些OverlappingInstances(或更糟糕的IncoherentInstances)更不可怕.
它抱怨的原因是因为MonadError有从功能依赖m于e.这意味着选择m决定了什么e; 即每个m只与一个相关联e.对此(对覆盖条件)的检查是保守的,因此很容易遇到这样的问题,在那里你尝试"递减一个级别"来指定e.
1它会列出它所看到的所有实例,试图找到它正在寻找的那个,所以你会看到一堆重复的线条.但通常你一开始就不会遇到这样的麻烦.