あなたはすでにすべての興味深い可能性を使い果たしていると思います。どれでも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、基本ケースとしてを使用して帰納的に推論するオプションがあります。たとえば、手元にある手段を使用して構築されたがあるとします。それ以外にも、以下の可能性があります。returnfmapuv :: m av
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)
これで、反例への明確な道筋ができました。適用法則を使用して両側を標準形に変換する場合、左側にはインターリーブされたusとvsが、右側にはすべて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効果が必ず違反につながるかを証明できますか?モナド射法則?