haskell-ja > Archives > 2009/10/30

2009/10/30 05:29:07 UTCkazu
#
Typeclassopedia を読んで疑問に感じたことがあるので、教えて下さい。
#
Functor, Pointed, Applicative, Monad は、以下のように定義できるとあります。
#
class Functor f where
  fmap :: (a -> b) -> f a -> f b

class Functor f => Pointed f where
  pure :: a -> f a     -- またの名を return

class Pointed f => Applicative f where
  (<*>) :: f (a -> b) -> f a -> f b

class Applicative m => Monad m where
  join :: m (m a) -> m a
#
Monad の制約が Pointed ではなく、Applicative なのはなぜでしょう?
#
pure が return、fmap と join で >>= が作れるので、<*> は不要な気がします。
2009/10/30 08:02:13 UTCsnak
#
逆にMonadであればApplicativeなので()、
#
Applicative制約がついているのではないでしょうか。
2009/10/30 09:26:46 UTCnobsun
#
Monad であれば Applicative ですが、Applicative であっても Monad とは限らないという関係を反映しているのだということかな。
2009/10/30 12:30:15 UTCkazu
#
うーん。どのクラスの基にどのクラスが乗っているかという図と、集合としての包含関係の図を一つで表すから分かりにくいのでしょうか?
#
ところで、RWH の Parsec の章で Applicative を使いますが、どうしてわざわざ力を弱めて Applicative を使うのでしょうか? <$> と <*> のところに、`liftM` と `ap` と書いても同じですよね? 演算子の方が読みやすいという以上の意味はあるのでしょうか?
2009/10/30 14:17:31 UTCnobsun
#
RWHでは演算子の方が読みやすいという意味だけだと思います。RWHでは他にもこういうところがたくさんあります。
#
firstを使うためだけに、Control.Arrowをインポートしたりしています。
#
そもそも、PreludeとControl.MonadとControl.ArrowとControl.Applicativeはそれぞれ導入の時期もずれていて、十分に整理されているわけではありません。
2009/10/30 14:51:42 UTCnobsun
#
ちょっといいすぎたかな > RWHでは演算子の方が読みやすいという意味だけだと思います
2009/10/30 15:00:26 UTCnobsun
#
RWHの著者らの感覚では、Applicative Functorでの説明がしっくり来るということなのだと思います。ApplicativeはMonadよりもArrowよりも新しくまとめられた抽象化なのでこのような部分がでるのだと思われます。(うう。うまく説明できてませんね。)
2009/10/30 19:27:12 UTCnwn
#
class Applicative m => Monad m where <-- ここの Applicative が pure も含んだ Applicative の方をさしてるからじゃないかな
  join :: m (m a) -> m a
2009/10/30 19:54:47 UTC[1..100]>>=pen
#
class Pointed m => Monad m where
#
join :: m (m a) -> m a
#
でも monad になるのになんで
#
Applicative m =>
#
にする必要があるのかという質問でしょう。
2009/10/30 20:04:00 UTCnwn
#
pen さんおっはー。Applicative が pure も含んでいるという文脈の上で提示されたコードだから、というのが僕の回答でした。
2009/10/30 20:14:37 UTCnwn
#
join を使った Monad の定義は Typeclassopedia の List 19 に出てくるコードですが、そこで扱われている Applicative はきれいなほう((<*>) だけをメソッドとして持つ)ではなく、現実の(pure と (<*>) をメソッドとして持つ) を指している。あと Monad にするためには (<*>) を定義する必要があるとも書いていなかったはずです