タイトルとは、Monad m => m (m a)
のようなタイプを意味します。
モナドの構造が単純な場合、そのような型の使用法を簡単に考えることができます。
多次元リストである_[[a]]
_
Maybe (Maybe a)
、2つのエラー状態が隣接するタイプ
Either e (Either e a)
、上記と同じですが、メッセージが表示されます
Monoid m => (m,(m,a))
。これは、2つの上書きを行うライターモナドです。
_r -> r -> a
_は、2つの読み取り元を持つリーダーモナドです。
Identity (Identity a)
、これはまだ恒等モナドです
Complex (Complex a)
、2行2列の行列
しかし、次のタイプについて考えると、頭がおかしくなります。
ReadP (ReadP a)
? ReadP
がRead
のインスタンスではないときになぜ役立つのですか?
ReadPrec (ReadPrec a)
?上記のように?
Monad m => Kleisli m a (Kleisli m a b)
?
IO (IO a)
!?これは必須が役に立ちます。それについて考えるのは難しい。
forall s. ST s (ST s a)
!?これは上記のようになります。
そのようなタイプの実用的な用途はありますか?特にIO
については?
2番目の考えでは、IO
アクションをランダムに選択する必要があるかもしれません。これは、入力に焦点を当てたIO (IO a)
の例です。出力に焦点を当てている人はどうですか?
関係ない。
すべてのMonad ( Monad a )
に対して常に_Monad a
_を取得できるため、モナドはモナドです。そのような操作は「結合」と呼ばれ、モナドの定義を形成できる「バインド」の代替操作です。 Haskellは "bind"を使用します。モナディックコードを作成するのに非常に便利だからです。
関係ない
Monad ( Monad a )
を形成する能力も、モナドをモナドにするものの事実上の一部であるため、実際には小さな嘘です。一部の操作では、Monad (Monad a)
は遷移表現です。
完全な答えは次のとおりです。はい、モナドを有効にするためです。いくつかのモナドについてリストするように、Monad ( Monad a )
は追加の「ドメイン」の意味を持つことができますが;)