2017-09-07 14 views
7

を定義しているモナド変圧器では、なぜ知っているモナドは内側のモナドですか?</p> <pre><code>newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a)} </code></pre> <p>でもない:例えば、<code>MaybeT</code>は次のように

newtype MaybeT m a = 
    MaybeT { runMaybeT :: Maybe (m a) } 

これはなぜでしょうか?

+1

私たちは 'Maybe'モナドを変形し、' Maybe'には何が含まれているのではないのですか? –

+0

これは前のどこかで答えられたと思いますが、私はそれを見つけることができません。 – leftaroundabout

答えて

6

newtypesを拡張した後、最初のケースではjoin :: Monad m => m (Maybe (m (Maybe a))) -> m (Maybe a)、次のケースではjoin :: Monad m => Maybe (m (Maybe (m a))) -> Maybe (m a)となります。あなたが逆の分配法則dist2 :: Monad m => m (Maybe a) -> Maybe (m a)

join2 :: Maybe (m (Maybe (m a))) -> Maybe (m a) 
join2 = fmap join . join . fmap dist2 

dist1が簡単である必要がある第二joinを実装するには

join1 :: m (Maybe (m (Maybe a))) -> m (Maybe a) 
join1 = fmap join . join . fmap dist1 

dist1 :: Monad m => Maybe (m a) -> m (Maybe a):あなたはmMaybeを配布する方法が必要最初joinを実装するために

実装する(私はあなたにモナド変圧器の法律を証明しておきます):

dist1 :: Monad m => Maybe (m a) -> m (Maybe a) 
dist1 = sequenceA 

dist2はあまり簡単ではありません。任意のMonadに対しては実行できません。あなたはrへのアクセスを持っていないので、です。TypeCheckますdist2の唯一の実装は「明確に勝った、const Nothingある

dist2 :: (r -> Maybe a) -> Maybe (r -> a) 

:反例として、「リーダー」モナド(->) rするのはmを選ぶみましょうモナドの法則を満たす。

+1

「join2」に焦点を当てることで、問題をどのように分解しなければならないかについてあまりにも深く考えるのではなく、簡単に問題を見ることができると思います。引数に対してパターンマッチングを行い、 'm(Maybe(m a)) - >たぶん(m a)'が必要です。唯一の重要な選択肢は 'Just'です。これは' m(Maybe(m a)) - > m a'につながります。これはトラブルのようなにおいをします。 – dfeuer

2

StateTを見てみると有益であるかもしれない:

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) } 

ここで状態は「内側」や「外側」もないですが、その種類は、それが変換されたモナド、内部のいくつかのビット、いくつかの外部とインタリーブされます。そして確かに

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a } 

はすべて「外側」です。だからそれは変圧器に依存します。多分このインターリーブを部分的に説明するいくつかのカテゴリ理論があります。私はそれについて知りたいと思っています(知識人?)。

newtype Compose f g a = Compose { getCompose :: f (g a) } 

も同様に応用可能であるので、明確な「外側/内側」の関係が常に存在しているために応用的ファンクタと

コントラスト。あなたはApplicativeの専用StateTを行い、Compose (State s)によってその構造を見つけることができます

ApplicativeStateT s f a = s -> (s, f a) 

実際には、あなたが右に構成した場合、別の1があります:

ApplicativeStateT' s f a = f (s -> (s,a)) 

しかし、モナドはそのような規則性を持っていません。

+1

私はいくつかの変圧器に与えた名前が間違ったパターンを示唆していると思う。 'State'の後に' StateT'と 'Reader'の後に' ReaderT'などと名前をつけます。これは何らかの一対一の関係を示唆しているようです。しかし、モナドとモナド変圧器は実際にはかなり異なっています。「正しい」モナド変圧器であると公言している様々なことが明らかです。パイプライン/コンジット/ストリーミング/マシン/コルーチンと '' LogicT'(そして '' LogicT''の反省のないバージョン)はすべて、タイトルに正当な主張を持っているようです。 – dfeuer

関連する問題