2016-09-22 8 views
3

私は現実世界のハスケルでモナールトランスを探していました。 モナド変圧器を作るには、MonadTrans型クラスのインスタンスにする必要があると言われています。モナドトランスフォーマーリフト

この本ではトランスフォーマーであるMaybeT m aが新たに定義されています。

彼らはこの新しい変圧器のためmonadTrans型クラスを定義しました。そして、彼らは、この変圧器のためのMonadStateのインスタンスを作っ

instance MonadTrans MaybeT where 
    lift m = MaybeT (Just `liftM` m) 

instance (MonadState s m) => MonadState s (MaybeT m) where 
    get = lift get 
    put k = lift (put k) 

私はリフト機能が取っている理解して何から基底のモナドを右のコンストラクタにラップします。しかし、私はMonadState型クラスのgetまたはputの実装を取得していませんが、ここで実際に何が起きているのか理解するのに役立つと思います。私はまた、タイプクラスがどのように定義されているかをmtlパッケージで知っていますが、WriterT、StateTなどでモナド変換器のスタックを使用できますが、get、put、tellなどの関数を実際に持ち上げることなく使用できます。私はこれがどのように機能するのだろうかと疑問に思っていました。これらのタイプのクラスとは強く関係していますが、わかりません。

答えて

1

いますが、実際にそれらの機能は、実際に、例えば上で定義されているためです

を持ち上げるをやってなくて、GET、PUT、伝えるなどのような関数を使用することができますMonadStateタイプはStateタイプではありません。その後

class Monad m => MonadState s m | m -> s where 
    get :: m s 
    put :: s -> m() 

、両方 StateStateTは、私たちが MaybeT mの内部モナドは(満たしていることがわかっている場合、あなたの例の場合では

可能それらを使用して行い、そのクラスのインスタンスを、作られています)MonadState sの場合、外側のモナド全体をMonadState sとして扱うことができます。内側のモナドに向けられた操作を持ち上げて、外側のモナドに適合させると、liftで終わります。平易な英語で

、それは "のようなものに聞こえるだろうタイプsためのステートフル(MonadState)モナドであるいくつかのモナドmオーバーMaybeTトランス変換(ラップ)は、結果の型は、そのタイプのためのステートフルモナドがある場合 "。


State s a実際StateT s Identity aとして実装されているので、これは、実際には単に一例です。実装の詳細についてはRefer to the sourcesを参照してください。

+0

もし私たちが 'MaybeT(State Int)String'のようなものを持っていたら、どうしたら実際の持ち上げがうまくいっているのか理解できないと思います。リフト機能に何が渡されていますか? – Zubair

+0

@Zubair 'lift'は内側のモナドに向けられたアクションを取り、それを外側のモナドに包み返します。 IOW、この特定のケースでは、 'lift :: State Int String - > MaybeT(State Int)String'です。 –