これは非常に素晴らしいです。現実の世界では、私の代わりに、あなたが与えた1のこの表記法の60%の確率で期待される:
C x c >>= f = C (value $ f x) (c + 1)
をしかし、それはそれは言及ほとんど価値があるので、軽微であります。
より深刻なことに、文体的ではなく意味論的なものです:これはモナドではありません。実際、それはモナド法の3つすべてに違反しています。 (>=>)
がf >=> g = \x -> f x >>= g
として定義されている。(>>=)
は、その後(>=>)
は、対応する組成演算子であり、「アプリケーション」演算子とみなされた場合。私は、この演算子を使用して第3法則を述べるのが好き、それは第3法則のを引き出すため
(1) return x >>= f = f x
(2) m >>= return = m
(3) m >>= (f >=> g) = (m >>= f) >>= g
(意味:結合性)これらの計算では
:。
(1):
return 0 >>= return
= C 0 0 >>= return
= C (value $ return 0) 1
= C 0 1
Not equal to return 0 = C 0 0
(2):
C 0 0 >>= return
= C (value $ return 0) 1
= C 0 1
Not equal to C 0 0
(3)
C 0 0 >>= (return >=> return)
= C (value $ (return >=> return) 0) 1
= C (value $ return 0 >>= return) 1
= C (value $ C 0 1) 1
= C 0 1
Is not equal to:
(C 0 0 >>= return) >>= return
= C (value $ return 0) 1 >>= return
= C 0 1 >>= return
= C (value $ return 0) 2
= C 0 2
これはあなたの実装では、単にエラーではありません - "バインドの数をカウント" というモナドはありません。それはは法律(1)と(2)に違反しなければなりません。あなたが法律(3)に違反しているという事実は、実装上の誤りです。
(>>=)
の定義にあるf
は、複数のバインドを持つアクションを返す可能性があり、無視しています。あなたは左と右の引数からバインドの数を追加する必要があります。
C x c >>= f = C y (c+c'+1)
where
C y c' = f x
これは正しくバインドの数をカウントします、と結合法である第3法則を、満足させます。それは他の2つを満たしません。しかし、+1
をこの定義から削除すると、はモノイド以上のWriter
モナドに相当する実際のモナドを取得します。これは基本的にすべてのサブコンピューティングの結果をまとめます。あなたは何かの数を数えるためにこれを使うことができます、ちょうどバインドしません - バインドはカウントするにはあまりにも特別です。しかし、例えば:次に
tick :: C()
tick = C() 1
C
は、計算で発生したtick
秒数をカウントします。
実際には、あなたはどの連想演算子を持つ任意の型を持つInt
と(+)
を交換し、モナドを得ることができます。これは一般的にはWriter
のモナドです。演算子が連想でない場合、これは3番目の法則に失敗します(理由は分かりますか?)。
これは私が期待していたものではありませんが、私が必要としていたものです。なぜ3番目の法則が壊れているのか?なぜなら、演算子が結合的でないならば、3番目の法則は結合の結合性であるからです。バインドが(私が "does"の正確な定義を与えることができない)アソシエイティブでないものを "行う"場合、それ自体はアソシエイティブでもありません。そうですか? – abesto
他にも:きれいな詳細な説明。ありがとうございました。 – abesto
時間をかけて説明してくれてありがとう! – Daniel