Monadとなる条件
ある型がMonad型クラスのinstanceとなればそれはMonadになるが、つまりどういうことか Monadであるための条件
以下の2つは同値
code:purs(hs)
pure :: a -> m a
bind :: m a -> (a -> m b) -> m b -- (>>=)
code:purs(hs)
map :: (a -> b) -> m a -> m b
pure :: a -> m a
join :: m (m a) -> m a
なぜなら、上のpure, bindがあれば、下のmap, joinを導出できる code:purs(hs)
map f m = m >>= (pure <<< f)
join m = m >>= identity
上記が結論だが、もう少し具体的に見てみるmrsekut.icon
Monadを構築するまでの型クラスの継承関係を見る
hsの場合
Functor
fmap
Applicative
pure
ap
Monad
return
bind
pursの場合
Functor
map
Apply
apply
Applicative
pure
Bind
bind
(ちなみにjoinもここで定義されている ref) Monad
この感じを見ても以下の4つの関数を実装していれば、Monadを作れそうということはわかる
map
apply
pure
bind
念の為書いておくと、pursとhsの対応は以下の感じ
table:対応
Haskell PureScript
fmap map
ap apply
pure, return pure
bind bind
しかし、pure, bindがあれば、map,applyは導出できる
mapについて
既に上で見たが再掲
code:purs(hs)
map f m = m >>= (pure <<< f)
applyについて
code:purs(hs)
apply f x = f >>= \f' -> x >>= \x' -> pure $ f' x'
doを使って書き換えると見やすくなる
code:purs(hs)
apply f x = do
f' <- f
x' <- x
pure $ f' x'
よって、pureとbindがあれば十分なのである
ちなみに、逆にjoinとmapから、bindを作ることも出来る
code:purs(hs)
bind :: m a -> (a -> m b) -> m b
bind x f = join $ map f x
参考