Haskeline:为`ReaderT r(StateT s m)`堆栈实现`MonadException`实例

时间:2013-08-19 21:40:44

标签: haskell

假设为了简单起见,我有以下monad变换器堆栈(rs()),

newtype MyMonad m a = MM (ReaderT () (StateT () m a)

如果我想将它用作haskeline的InputT的基础monad,我需要一个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?如何实现这个实例而不是开放编码呢?

1 个答案:

答案 0 :(得分:5)

状态monad有两个版本:strictlazyimport Control.Monad.State brings in the lazy version,但MonadException的实例似乎是严格版本。

尝试使用import Control.Monad.State.Strict代替import Control.Monad.State