0

は、私がいる間、指定されたスタックの上部と下部で、モナド変圧器スタックを受け付ける関数を作成しようとしています次のスニペット任意のモナド変圧器スタック

本質的には
import Control.Monad.Trans 
import Control.Monad.Trans.Except 
import Control.Monad.Trans.State 

newtype MyTransT m a = MyTransT (m a) 

foo :: (MonadTrans t, Monad (t (Either e))) => MyTransT (t (Either e)) a -> a 
foo = undefined 

bar :: MyTransT (StateT Int (Either e)) a 
bar = undefined 

baz :: MyTransT (StateT Int (StateT Int (Either e))) a 
baz = undefined 

x = foo bar -- works 

y = foo baz -- doesn't work 

を考えてみましょう真ん中は何でもかまいません。

foo bazCouldn't match type ‘StateT Int (Either e1)’ with ‘Either e0’で拒否された理由としてしばらくの間、私の頭を悩また後、最終的にそのような場合には、私はtはそのが正しく入力されたではない、だけではないMonadTransされていないStateT Int (StateT Int)だったと仮定したことが私に起こりました/ kinded。

私がしようとしていることを達成する方法はありますか、それとも別のアプローチを試みるのですか?

+0

実際に 'foo'をどのように動作させるかの具体例を挙げることができますか? – ErikR

+0

タイプが 'T'であるとします。これは' K'タイプのキーで 'V'タイプのコンテナと考えることができます。今度は、それぞれの「V」もこのパターンに従うと想像してください。私は 'foo :: StateT V(t(Either e))a - > StateT T(ReaderT K(t(Either e)))'をしたいと思います。これは 'V'を介してステートフルな操作を行い、' K'の環境を持つ 'T'を介してステートフルな操作に持ち上げます。基本的には、既存のコードを変更することなく、無限に上下に拡張できるツリー構造です。 – user2085282

+0

ここで具体的な例が役立ちます。あなたの質問にそれを入れて、読みやすいようにしてください。 – ErikR

答えて

0

tEither eモナドを超える変圧器ではないので、foo bazがチェックするのは、StateT Int (Either e)モナドを超える変圧器です。ここで

は、それが解析される方法です。

baz :: MyTransT (StateT Int (StateT Int (Either e))) a 
        \________/ \_____________________/ 
         t   m     a 

mフォームEither eではないこと。

新しいトランスを作成することができます。このようなStateTIntStateTInt、および書き込み バズ:

baz :: MyTransT (StateTIntStateInt (Either e)) a 

し、それがチェックを入力します。例えば:

type StateTIntStateTInt = StateT (Int,Int) 

baz' :: MyTransT (StateTIntStateTInt (Either e)) a 
baz' = undefined 

test = foo baz' 

はしかし、あなたはタイプの問題を回避しても、私はあなたが機能fooを書くことができるように を予定している疑い。 barのこの特定の値を を返却すべきか考えてみましょう:

bar0 :: MyTransT (StateT Int (Either String)) Int 
bar0 = MyTransT $ lift $ Left "blather" 

のInt値がfoo bar0返す必要がありますか?

+0

私はこれを理解し、質問にそれを指摘します。ポイントは、 'foo'が任意のスタックのトランスを受け入れることができるはずだから、すべての可能性についてnewtypeを作成することはありそうもないようです。また、 'foo'の戻り値の型はプレースホルダですが、スニペットは問題を示すためのものです。実際には 'foo'は' t(Either e) 'に関連する値を返します。 – user2085282

関連する問題