あなたはすでにすべての興味深い可能性を使い果たしていると思います。どれでもMonad m => m a -> m a
私たちが定義する可能性がある機能は必然的に次のようになります。
e :: forall m a. Monad m => m a -> m a
e u = u >>= k
where
k :: a -> m a
k = _
具体的には、もしk = return
、e = id
。以下のためe
ではないとid
、k
使用しなければならないu
(例えば、非自明な方法で、k = const u
かつk = flip fmap u . const
量あなたの2回の試行に)。ただし、そのような場合、u
効果は重複e
するため、モナドのいくつかの選択肢でモナドモーフィズムになりませんm
。そのため、モナドで完全に多態性を示す唯一のモナドモーフィズムはid
です。
引数をより明確にしましょう。
わかりやすくするために、少しの間、join
/ return
/ fmap
プレゼンテーションに切り替えます。実装したいもの:
e :: forall m a. Monad m => m a -> m a
e u = _
右側を何で満たすことができますか?最も明白な選択はu
です。それ自体ではe = id
、は面白くありません。ただし、およびもあるのでjoin
、基本ケースとしてを使用して帰納的に推論するオプションがあります。たとえば、手元にある手段を使用して構築されたがあるとします。それ以外にも、以下の可能性があります。return
fmap
u
v :: m a
v
join (return v)
でありv
、したがって、何も新しいことを教えてくれません。
join (fmap return v)
であり、これv
も同様に、そして
join (fmap (\x -> fmap (f x) w) v)
、w :: m a
私たちのルールに従って構築された他のものと、いくつかのためにf :: a -> a -> a
。(追加m
のタイプに層f
のように、a -> a -> m a
と、余分なjoin
のを私たちはその後、これらの層の出所を表示しなければならないとして、どこにもつながらないそれらを削除するには、物事は最終的には他のケースに減少するであろう。)
唯一の興味深いケースは#3です。この時点で、ショートカットを作成します。
join (fmap (\x -> fmap (f x) w) v)
= v >>= \x -> fmap (f x) w
= f <$> v <*> w
任意の非u
右側は、従って、形で表すことができるf <$> v <*> w
と、v
そしてw
いずれかでu
、最終的に到達する、またはこのパターンのさらなる反復u
の葉で秒。ただし、この種の適用表現は、適用法則を使用(<*>)
して左側のすべての使用を再関連付けすることによって取得される標準的な形式を持っています。この場合は、このようになります...
c <$> u <*> ... <*> u
...省略記号は、ゼロまたはそれ以上のさらなる発生放置とu
によって分離され<*>
、そしてc
あるa -> ... -> a -> a
適切なアリティの機能。a
は完全にポリモーフィックであるためc
、パラメトリックconst
性により、引数の1つを選択するような関数である必要があります。そういうわけで、そのような表現は(<*)
andの観点から書き直すことができます(*>)
...
u *> ... <* u
...のゼロまたはそれ以上のさらなる発生のために立って省略記号とのu
いずれかで区切られていない*>
か<*
、全くそこにいる*>
の右側にあります<*
。
最初に戻ると、id
候補以外のすべての実装は次のようになります。
e u = u *> ... <* u
またe
、モナド射になりたいです。結果として、それは適用可能な射でもあるに違いありません。特に:
-- (*>) = (>>) = \u v -> u >>= \_ -> v
e (u *> v) = e u *> e v
あれは:
(u *> v) *> ... <* (u >* v) = (u *> ... <* u) *> (v *> ... <* v)
これで、反例への明確な道筋ができました。適用法則を使用して両側を標準形に変換する場合、左側にはインターリーブされたu
sとv
sが、右側にはすべてv
のsの後にすべてu
のs が(まだ)残ります。プロパティは、モナドのために保持しないことを意味しますが好きIO
、State
またはWriter
、関係なく、どのように多くの(*>)
と(<*)
、そこにあるe
、または正確な値がで選ばれていますconst
いずれかの側の様な機能。簡単なデモ:
GHCi> e u = u *> u <* u -- Canonical form: const const <$> u <*> u <*> u
GHCi> e (print 1 *> print 2)
1
2
1
2
1
2
GHCi> e (print 1) *> e (print 2)
1
1
1
2
2
2
u
が必然的に複製されることを証明するにはどうすればよいe = id
ですか?(e u = do _ <- u; _ <- u; _ <- u; u
さらに-u
効果を記述して組み合わせることもできます。)「モナディック値にp :: m a
は複数の効果がコピーされていることを数学的u :: m a
にどのように説明できますか?そして、どのようにして重複(三重など)u
効果が必ず違反につながるかを証明できますか?モナド射法則?