ライターモナドとリストライターモナドの違いは何ですか

ルパート風

私はそれがどのように機能するかを理解するためにライターモナドの例を見ていました、そしてそれらのほとんどすべてはリストライターモナドのように見えます。リストライターモナドはライターモナドの一種であることを私は知っています。しかし、素人の言葉で言えば、作家のモナドとは何ですか。

Rein Henrichs

簡単に言うと、ライターモナドは、値を生成しながらアイテムを「ログ」に「書き込む」ことができるモナドです。完了すると、作成した値作成たすべてのものを含むログが作成されます。別の言い方をすれば、副作用が「ログへの書き込み」であるモナドです。

リストライターと(一般的な)ライターモナドの両方の例を使用して、これをより具体的にしましょう。ここではHaskellを使用します。これは、関数型プログラミングのモナドが説明された元のコンテキストだからです。

リストライターモナド

「リストライター」モナドは、アイテム(もちろん、あるwタイプの[w])をアイテムのリスト(もちろん、タイプの)に記録するモナドだと思いますまた、タイプの値を生成しますa(このコードを自分で使用してエラーが発生した場合は、下部の注を参照してください。)

newtype ListWriter w a = ListWriter { runListWriter :: ([w], a) }

instance Monad (ListWriter w) where
  return a = ListWriter ([], a)    -- produce an a, don't log anything
  ListWriter (ws, a) >>= k =
    let ListWriter (xs, a') = k a  -- run the action 'k' on the existing value,
    in ListWriter (ws ++ xs, a')   -- add anything it logs to the existing log, 
                                   -- and produce a new result value

-- Add an item to the log and produce a boring value.
-- When sequenced with >>, this will add the item to existing log.
tell :: w -> ListWriter w ()
tell w = ListWriter ([w], ())

ex1 :: ListWriter String Int
ex1 = do
  tell "foo"
  tell "bar"
  return 0

(注:これはex1 = tell "foo" >> tell "bar" >> return 0と同等でありtellwith>>使用てアイテムをログに追加する方法を示しています。)

runListWriter ex1GHCiで評価すると、ログに「foo」と「bar」が書き込まれ、結果値が生成されたことがわかります0

λ> runListWriter ex1
(["foo","bar"],0)

(ジェネリック)ライターモナド

それでは、これを一般的なライターモナドに変換する方法を見てみましょう。ライターモナドは、リストだけでなく、組み合わせることができるあらゆる種類のもので機能します。具体的には、次のいずれかで機能しますMonoid

class Monoid m where
  mempty :: m            -- an empty m
  mappend :: m -> m -> m -- combine two m's into a single m

リストは、それぞれ[](++)asmemptyasとのモノイドmappendです。モノイドのリスト以外の例は、整数の合計です。

λ> Sum 1 <> Sum 2        -- (<>) = mappend
Sum {getSum = 3}

作家のモナドは

newtype Writer w m = Writer { runWriter :: (w, m) }

w'のリストの代わりに、単一のwがあります。しかし、モナドを定義するときwは、Monoidそれが空のログから始めてログに新しいエントリを追加できるようにするためです。

instance Monoid w => Monad (Writer w) where
  return a = Writer (mempty, a)   -- produce an a, don't log anything
  Writer (w, a) >>= k =
    let Writer (x, a') = k a      -- we combine the two w's rather than 
    in Writer (w <> x, a')        -- (++)-ing two lists

ここでの違いに注意してください。のmempty代わりに[]、の(<>)代わりにを使用します(++)これが、リストから任意のモノイドに一般化する方法です。

したがって、ライターモナドは、実際には、リストモナドを、単なるリストではなく、組み合わせることができる任意のものに一般化したものです。でリストを使用して、Writer(ほぼ)同等のものを取得できますListWriter唯一の違いは、ログに追加するときに、ログに記録されたアイテムをリストでラップする必要があることです。

ex2 :: Writer [String] Int
ex2 = do
  tell ["foo"]
  tell ["bar"]
  return 0

しかし、同じ結果が得られます。

λ>  runWriter ex2
(["foo","bar"],0)

これは、「リストに入れられるアイテム」をログに記録する代わりに、「リスト」をログに記録しているためです。(これは、複数の要素のリストを渡すことで、同時に複数のアイテムをログに記録できることを意味します。)

Writerのリスト以外の使用例については、ソート関数が行う比較をカウントすることを検討してください。関数が比較を行うたびに、次のことができtell (Sum 1)ます。(誰かに言うことができます。それを取得しますか?これはオンですか?)そして、最後に、ソートされたリストとともに、すべての比較の合計数(つまり、合計)を取得します。


注:これらListWriterWriter定義を自分で使用しようとする、GHCはインスタンスFunctorApplicativeインスタンスが欠落していることを通知ます。Monadインスタンスを取得したら、他インスタンスをその用語で記述できます。

import Control.Monad (ap, liftM)

instance Functor (ListWriter w) where
  fmap = liftM

instance Applicative (ListWriter w) where
  pure = return
  (<*>) = ap

そして同様にWriterわかりやすくするために、上記では省略しました。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

モナドコレクション、モナドタイプ、モナド操作の違いは何ですか?

分類Dev

リストのライターモナドはどれくらい効率的ですか?

分類Dev

Javaのイベントリスナーとハンドラーの違いは何ですか?

分類Dev

Kubernetesのドライバーとコンテナーランタイムの違いは何ですか?

分類Dev

ファンクターとモナドの違いは何ですか?

分類Dev

LPRドライバーとcupswrapperドライバーの違いは何ですか?プリンタードライバーのインストール方法は?

分類Dev

インメモリデータベースとリレーショナルデータベース+ NoSQLデータベースの違いは何ですか?

分類Dev

ダートのアナライザーとリンターの違いは何ですか?

分類Dev

NVIDIAレガシーバイナリプロプライエタリドライバとバイナリのみのプロプライエタリドライバの違いは何ですか?

分類Dev

LinuxMintシナモンのウィンドウのタイリングとスナップの違いは何ですか

分類Dev

SATAドライブ:IDEモードとAHCIの違いは何ですか?

分類Dev

Scalaのファイナルクラスとシールドクラスの違いは何ですか?

分類Dev

ターミナル、コンソール、シェル、コマンドラインの違いは何ですか?

分類Dev

ターミナル、コンソール、シェル、コマンドラインの違いは何ですか?

分類Dev

ScalazライターモナドとfilterM

分類Dev

アマゾンインスペクターvsトラストアドバイザーvsクラウドウォッチvsパーソナルヘルスダッシュボードvsAWSクラウドトレイルの違いは何ですか?

分類Dev

スナップのクラシックモードとは何ですか?また、一部のスナップがスナップなしでインストールされないのはなぜですか(MS Visual Studioなど)?

分類Dev

スナップのクラシックモードとは何ですか?また、一部のスナップがスナップなしでインストールされないのはなぜですか(MS Visual Studioなど)?

分類Dev

画像のバイナリデータとGPUがモニターに送信する変換されたデータの違いは何ですか?

分類Dev

ライターモナドの使用

分類Dev

型コンストラクターはモナドですか、それともモナドを持っていますか?

分類Dev

モナドトランスフォーマーがスタッキングモナドと異なるのはなぜですか?

分類Dev

ノーチラスでルートモードのときにターミナルが開かない。何をすべきか?

分類Dev

コードイグナイターで呼び出されるヘルパーとライブラリの方法に違いはありますか?

分類Dev

フィールドでのインスタンス化とコンストラクターでのインスタンス化の違いは何ですか?

分類Dev

スレッドのサブクラスのオブジェクトをインスタンス化するために継承とポリモーフィズムを使用することの主な違いは何ですか?

分類Dev

スレッドのサブクラスのオブジェクトをインスタンス化するために継承とポリモーフィズムを使用することの主な違いは何ですか?

分類Dev

C ++ ifstream、ofstream:生のread()/ write()呼び出しとバイナリモードでファイルを開くことの違いは何ですか?

分類Dev

C ++ ifstream、ofstream:生のread()/ write()呼び出しとバイナリモードでファイルを開くことの違いは何ですか?

Related 関連記事

  1. 1

    モナドコレクション、モナドタイプ、モナド操作の違いは何ですか?

  2. 2

    リストのライターモナドはどれくらい効率的ですか?

  3. 3

    Javaのイベントリスナーとハンドラーの違いは何ですか?

  4. 4

    Kubernetesのドライバーとコンテナーランタイムの違いは何ですか?

  5. 5

    ファンクターとモナドの違いは何ですか?

  6. 6

    LPRドライバーとcupswrapperドライバーの違いは何ですか?プリンタードライバーのインストール方法は?

  7. 7

    インメモリデータベースとリレーショナルデータベース+ NoSQLデータベースの違いは何ですか?

  8. 8

    ダートのアナライザーとリンターの違いは何ですか?

  9. 9

    NVIDIAレガシーバイナリプロプライエタリドライバとバイナリのみのプロプライエタリドライバの違いは何ですか?

  10. 10

    LinuxMintシナモンのウィンドウのタイリングとスナップの違いは何ですか

  11. 11

    SATAドライブ:IDEモードとAHCIの違いは何ですか?

  12. 12

    Scalaのファイナルクラスとシールドクラスの違いは何ですか?

  13. 13

    ターミナル、コンソール、シェル、コマンドラインの違いは何ですか?

  14. 14

    ターミナル、コンソール、シェル、コマンドラインの違いは何ですか?

  15. 15

    ScalazライターモナドとfilterM

  16. 16

    アマゾンインスペクターvsトラストアドバイザーvsクラウドウォッチvsパーソナルヘルスダッシュボードvsAWSクラウドトレイルの違いは何ですか?

  17. 17

    スナップのクラシックモードとは何ですか?また、一部のスナップがスナップなしでインストールされないのはなぜですか(MS Visual Studioなど)?

  18. 18

    スナップのクラシックモードとは何ですか?また、一部のスナップがスナップなしでインストールされないのはなぜですか(MS Visual Studioなど)?

  19. 19

    画像のバイナリデータとGPUがモニターに送信する変換されたデータの違いは何ですか?

  20. 20

    ライターモナドの使用

  21. 21

    型コンストラクターはモナドですか、それともモナドを持っていますか?

  22. 22

    モナドトランスフォーマーがスタッキングモナドと異なるのはなぜですか?

  23. 23

    ノーチラスでルートモードのときにターミナルが開かない。何をすべきか?

  24. 24

    コードイグナイターで呼び出されるヘルパーとライブラリの方法に違いはありますか?

  25. 25

    フィールドでのインスタンス化とコンストラクターでのインスタンス化の違いは何ですか?

  26. 26

    スレッドのサブクラスのオブジェクトをインスタンス化するために継承とポリモーフィズムを使用することの主な違いは何ですか?

  27. 27

    スレッドのサブクラスのオブジェクトをインスタンス化するために継承とポリモーフィズムを使用することの主な違いは何ですか?

  28. 28

    C ++ ifstream、ofstream:生のread()/ write()呼び出しとバイナリモードでファイルを開くことの違いは何ですか?

  29. 29

    C ++ ifstream、ofstream:生のread()/ write()呼び出しとバイナリモードでファイルを開くことの違いは何ですか?

ホットタグ

アーカイブ