比方說,我有以下的單子轉換堆棧(r
和s
留給()
爲簡單起見),Haskeline:實現`爲`ReaderT R(StateT SM)MonadException`例如`堆棧
newtype MyMonad m a = MM (ReaderT() (StateT() m a)
如果我想要使用這個作爲基礎monad的haskeline的InputT
,我需要一個System.Console.Haskeline.MonadException
實例。鑑於這些實例的apparent complexity,我寧願讓編譯器通過GeneralizedNewtypeDeriving
爲我推導這個。具體來說,我希望下面來進行類型檢查,
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, FlexibleContexts #-}
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.IO.Class
import Control.Applicative
import System.Console.Haskeline.MonadException
newtype MyMonad m a = MM (ReaderT() (StateT() m) a)
deriving (Functor, Applicative, Monad, MonadIO)
deriving instance (MonadException m) => MonadException (MyMonad m)
然而可悲的是,這給了我,
/home/bgamari/hi.hs:11:1:
Could not deduce (MonadException (StateT() m))
arising from the superclasses of an instance declaration
from the context (MonadIO (MyMonad m), MonadException m)
bound by the instance declaration at /home/bgamari/hi.hs:11:1-66
Possible fix:
add an instance declaration for (MonadException (StateT() m))
In the instance declaration for `MonadException (MyMonad m)'
在爲StateT
和ReaderT
所提供的情況來看,
instance MonadException m => MonadException (ReaderT r m)
instance MonadException m => MonadException (StateT s m)
似乎期望編譯器推斷出StateT
實例是完全合理的。我是否期待太多的狡猾GeneralizedNewtypeDeriving
?如何實現這個實例缺少開放編碼?
是的,你似乎是對的。我認爲這實際上使這個問題成爲問題#16944016的重複 – bgamari