2013-08-19 40 views
1

比方說,我有以下的單子轉換堆棧(rs留給()爲簡單起見),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)' 

在爲StateTReaderT所提供的情況來看,

instance MonadException m => MonadException (ReaderT r m) 
instance MonadException m => MonadException (StateT s m) 

似乎期望編譯器推斷出StateT實例是完全合理的。我是否期待太多的狡猾GeneralizedNewtypeDeriving?如何實現這個實例缺少開放編碼?

回答

5

狀態單元有兩個版本:strictlazyimport Control.Monad.Statebrings in the lazy version,但MonadException的實例似乎是嚴格的版本。

import Control.Monad.State.Strict而不是import Control.Monad.State來嘗試。

+0

是的,你似乎是對的。我認爲這實際上使這個問題成爲問題#16944016的重複 – bgamari