29

私はモナドが何であるかを知っています。コモナドとは何かについて、私は正しく理解できたと思います(というか、これ単純に思えますが、これの何が役に立つのかを理解するのが難しい部分です...)

私の質問は次のとおりです。何かがモナドコモナドになることができますか?

考えられる答えは 2 つあると思います。

  • はい、これは一般的で広く有用です。
  • いいえ、彼らは非常に異なる仕事をしているので、何かを両方にしたい理由はありません.

それで、それはどれですか?

4

5 に答える 5

24

はい。いくつかのコメントを答えに変える:

newtype Identity a = Identity {runIdenity :: a} deriving Functor
instance Monad Identity where
  return = Identity
  join = runIdentity
instance CoMonad Identity where
  coreturn = runIdentity
  cojoin = Identity

で示されるように、Reader と Writer は厳密な双対です。

class CoMonoid m where
  comempty :: (m,a) -> a
  comappend :: m -> (m,m)
--every haskell type is a CoMonoid
--that is because CCCs are boring!

instance Monoid a => Monad ((,) a) where
  return x = (mempty,x)
  join (a,(b,x)) = (a <> b, x)
instance CoMonoid a => CoMonad ((,) a) where
  coreturn = comempty
  cojoin = associate . first comappend

instance CoMonoid a => Monad ((->) a) where
  return = flip (curry comempty)
  join f = uncurry f . comappend
instance Monoid a => CoMonad ((->) a)  where
  coreturn f = f mempty
  cojoin f a b = f (a <> b)
于 2013-05-14T20:34:45.067 に答える
17

Monadと の両方である興味深い構造がたくさんありますComonad

ファンクターは他のIdentity何人かによってここで指摘されていますが、自明ではない例があります。

はとしてWriter MonadReaderような役割を果たしComonadます。

instance Monoid e => Monad ((,) e)
instance Comonad ((,) e)

はとしてReader MonadWriterような役割を果たしComonadます。

instance Monad ((->) e)
instance Monoid e => Comonad ((->)e)

空でないリストもモナドと共通モナドの両方を形成し、実際には共自由共通モナドを含むより大きな構造の特殊なケースです。このIdentityケースは、この特殊なケースと見なすこともできます。

また、Kan 拡張に基づくさまざまな and に似た構造もありYonedaCodensityモナドとコモナドを変換するために機能しますが、操作効率の点ではどちらか一方に有利です。

また、任意の共通モナドをモナド変換子に変換するアダプターもあります。残念ながら、Haskell では逆の変換はできません。

線形代数には双代数の概念がありますMonad理想的には、aと a の両方を形成する何かがありComonad、ケースバイケースで推論せずにこれらの操作を一緒に使用したい場合、returnそれjoinは Comonad 双極数であり、拡張によりextractduplicateMonad代数です。Monad fこれらの条件が当てはまる場合、実際には、 と の両方のComonad f制約を持ち、ケースバイケースの推論なしでそれぞれのコンビネータを混合するコードについて推論することができます。

于 2013-05-19T18:57:50.303 に答える
1

Hammer の提案を拡張すると、 function を書くのは簡単に思えます[x] -> [[x]]。例えば、

map (\ x -> [x])

うまくいくでしょう。したがって、リストは共通項を形成できるように見えます。あ、でも待って。それは を扱いますcojoinが、どうcoreturn :: [x] -> xですか?おそらくこれが、空でないリストだけが共通項を形成する理由です。

これにより、 type の cobind 関数が得られます([x] -> x) -> [x] -> [x]。興味深いことに、Hoogle はそのような関数を知りません。それでも、私たちはすでに持っていますconcatMap :: (x -> [x]) -> [x] -> [x]。cobind 関数がすぐに使用されるとは思えませんが、存在することは想像できます。

私はまだcomonadとそれが何に役立つかについて頭を悩ませようとしています。これまでの回答は、私に考えさせる何かを与えてくれました...

于 2013-05-16T07:45:48.390 に答える