data InterpreterM a = ExeInterpreter a | PropInterpreter a
newtype InterpreterMT m a = InterpreterMT { runInterpreterMT :: m (InterpreterM a) }
instance (Monad m) => Monad (InterpreterMT m) where
return x = lift . return
x >>= f = InterpreterMT $ do
m <- runInterpreterMT x
case m of
(ExeInterpreter a) -> runInterpreterMT (f a)
instance MonadTrans InterpreterMT where
lift m = lift . (ExeInterpreter m)
を持ち上げ、私はエラーを持っている、と私は理由を知りません:あなたはいけない自分のモナド変圧器と
Interpreter.hs:25:20:
Couldn't match expected type `InterpreterMT m a'
with actual type `a2 -> t1 m1 a2'
In the expression: lift . return
In an equation for `return': return x = lift . return
In the instance declaration for `Monad (InterpreterMT m)'
Interpreter.hs:32:18:
Couldn't match expected type `InterpreterMT m a'
with actual type `a0 -> t0 m0 a1'
In the expression: lift . (ExeInterpreter m)
In an equation for `lift': lift m = lift . (ExeInterpreter m)
In the instance declaration for `MonadTrans InterpreterMT'
Interpreter.hs:32:27:
Couldn't match expected type `a0 -> m0 a1'
with actual type `InterpreterM (m a)'
In the return type of a call of `ExeInterpreter'
Probable cause: `ExeInterpreter' is applied to too many arguments
In the second argument of `(.)', namely `(ExeInterpreter m)'
In the expression: lift . (ExeInterpreter m)
私は、これは 'InterpreterMT(リターン(PropInterpreter A))>> = return' =' InterpreterMT(リターン(ExeInterpreter A))ことを必要と考えます'違反するx >> = return = x' – Michael
あなたはまったく正しいです。これは簡略化されたEitherTの定義ですが、重要な違いは、Typeパラメータが1つしかなく、Eitherのように2つではないことです。 '(PropInterpreter a)return(PropInterpreter a)'のようにcase式を変更する必要がありますが、 'InterpreterMT m a'で指定された' InterpreterMT m b'と一致しないので、型チェッカーはエラーを投げます。残念ながら私はこれに対する解決策を知らない。 – Cirquit
そうですね、どちらの場合も、 'a'に' f'を適用してから、再び一致して結果を組み立てるべきです。この回答は、[彼の他の質問](http://stackoverflow.com/questions/37187933/lift-monad-reader-local/37190716#37190716)私はちょうどInterpreterMTを(ある種の)Monoid + WriterTに還元する答えはあまりにも複雑で実用的ではありません。私は正しいモナドインスタンスが効果的に(m、)/ WriterT m – Michael