2012-03-30 38 views
5

如果轉換後的Monad是一個實例,我想讓我的monad變換器成爲MonadError的一個實例。基本上,我想我的變壓器表現爲內置變壓器做,例如有一個MonadError實例StateT製作一個MonadError實例的自定義monad變換器

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

我試着這樣做:

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

但GHC開始抱怨無法判定實例,顯然MTL庫只是啓用不可判定的實例,但有什麼辦法可以避免這種情況?或者在這種情況下,它不會導致任何問題?

回答

8

這基本上沒問題。 UndecidableInstances並不是那麼可怕;所有這一切意味着編譯器可以代替查找實例,進入無限循環。那聽起來非常糟糕,直到你意識到GHC實際上對找到一個實例需要的步數有限制;除非你編寫了一個不好的實例,否則沒有什麼會出錯的,並且你得到的錯誤信息通常會使問題變得非常明顯。 當然,它比諸如OverlappingInstances(或更糟糕的是,IncoherentInstances)更可怕。

它抱怨的原因是因爲MonadError的功能依賴關係從me。這意味着m的選擇決定了e必須是什麼;即,每個m僅與一個e相關聯。這個檢查(Coverage條件)是保守的,所以很容易遇到這樣的問題,在那裏你嘗試和「遞減一個級別」來指定e

它會列出所有查看的實例並找到它正在查找的實例,以便您看到一堆重複行。但通常情況下,你最初不會遇到這樣的麻煩。

相關問題