1

假设我有以下单子变压器堆栈(为简单起见r,请s留下()),

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

如果我想将它用作 haskeline's 的基本 monad InputT,我需要一个System.Console.Haskeline.MonadException实例。鉴于这些实例的明显复杂性,我宁愿让编译器为我派生出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吗?如果没有开放编码,如何实现这个实例?

4

1 回答 1

5

State monad 有两个版本:strictlazyimport Control.Monad.State 引入了惰性版本,但实例MonadException似乎是针对严格版本的。

尝试使用import Control.Monad.State.Strict而不是import Control.Monad.State.

于 2013-08-19T22:05:12.553 回答