15

Haskellに2つの異なるライタータイプのモナドがあるのはなぜですか?私にとって直感的には、「strict writer monad」を読むことは、<>が厳密であることを意味するため、ログにサンクが蓄積することはありません。ただし、ソースコードを見ると、そうではないことがわかります。

-- Lazy Writer
instance (Monoid w, Monad m) => Monad (WriterT w m) where
-- ...
m >>= k  = WriterT $ do
    ~(a, w)  <- runWriterT m
    ~(b, w') <- runWriterT (k a)
    return (b, w <> w')

厳密なバージョンでは、パターンは反駁できません。つまり、パターン~が欠落しています。したがって、上記で発生するのは、m評価k aされず、サンクとして保存されることです。厳密なバージョンでは、タプルパターンと一致するかどうかを確認するために評価され、結果がに送られ<>ます。どちらの場合も、>>=何かが実際に結果の値を要求するまで、は評価されません。だから私が理解しているのは、レイジーバージョンとストリクトバージョンの両方が同じことをするということです。ただし、レイジーはサンクを>>=生成しrunWriterT、ストリクトはサンクを生成し<>ます。

これは私に2つの質問を残します:

  1. 上記は正しいですか、それともここでの評価を誤解していますか?
  2. <>独自のラッパーとインスタンスを作成せずにstrictを達成できますか?
4

1 に答える 1

17

最初の観察は正しいですが、サンクが作成されるこの区別は重要です。

Lazyログタイプの厳密さでStrictはなく、ペアの厳密さについてです。

これらは、Haskellのペアがそれを更新する2つの可能な方法を持っているために発生します。

bimap f g (a,b) = (f a, g b)

また

bimap f g ~(a,b) = (f a, g b)

後者はと同じです

bimap f g p = (f (fst p), g (snd p))

これら2つの違いはbimap、最初のケースで引数をに渡すと、ペアがすぐに強制されることです。

後者の場合、ペアはすぐには強制されませんが、代わりに(,)2つの非厳密な計算で満たされたバックを渡します。

この意味は

fmap f _|_ = _|_ 

最初のケースではしかし

fmap f _|_ = (_|_, _|_)

2番目の怠惰なペアの場合!

ペアの概念の異なる解釈の下では、両方とも正しいです。ペアは、それ自体に興味深いものがないという、カテゴリ的な意味でのペアであるかのように見せかけることによって、あなたに強制されます_|_。一方、ドメインの解釈は厳密ではありません。できるだけ多くのプログラムを終了させることができるように、可能な限りLazyバージョンに誘導します。

(,) eは完全に許容Writerできるので、これが問題の特徴です。

区別される理由は、モナドを介して固定小数点をとる多くのエキゾチックなプログラムの終了にとって重要であるためです。怠惰である限り、州または作家が関与する特定の循環プログラムに関する質問に答えることができます。

どちらの場合も、「log」引数でこれが厳密ではないことに注意してください。適切な結合性を失い、技術的にはでなくなるという厳格さを被るとMonad、= /

これはモナドではないため、mtl!では提供しません。

これで、2番目の質問に答えることができます。

ただし、いくつかの回避策があります。Writerの上に偽物を作成できますState。基本的に、州の議論が渡されていないふりをします。そして、あなたがそうするように、ちょうど状態にmappendしますtell。これは厳密に行うことができます。これは、すべてのバインドの一部として背後で発生するわけではないためです。はState、アクション間で変更されていない状態を通過しているだけです。

shout :: Monoid s => s -> Strict.StateT s m ()
shout s' = do
   s <- get
   put $! s <> s'

Stateただし、これは、モナド全体に出力を強制的に取得させ、Monoid遅延の一部を生成できないことを意味しますが、厳密なプログラマーが期待するものに操作上近いものを取得します。興味深いことに、これはSemigroup、だけでも機能します。これは、の最初の使用memptyが効果的に行われるためですrunState

于 2013-02-01T14:37:41.120 に答える