Monadとなる条件
ある型が
Monad型クラスのinstanceとなればそれはMonadになるが、つまりどういうことか
Monadであるための条件
以下の2つは同値
purs(hs)pure :: a -> m a
bind :: m a -> (a -> m b) -> m b -- (>>=)
purs(hs)map :: (a -> b) -> m a -> m b
pure :: a -> m a
join :: m (m a) -> m a
なぜなら、上の
pure
,
bind
があれば、下の
map
,
joinを導出できる
purs(hs)map f m = m >>= (pure <<< f)
join m = m >>= identity
上記が結論だが、もう少し具体的に見てみる

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の対応は以下の感じ
対応Haskell | PureScript |
| |
fmap | map |
ap | apply |
pure, return | pure |
bind | bind |
しかし、 pure
, bind
があれば、 map
, apply
は導出できる
map
について
既に上で見たが再掲
purs(hs)map f m = m >>= (pure <<< f)
apply
について
purs(hs)apply f x = f >>= \f' -> x >>= \x' -> pure $ f' x'
do
を使って書き換えると見やすくなる
purs(hs)apply f x = do
f' <- f
x' <- x
pure $ f' x'
よって、 pure
と bind
があれば十分なのである
ちなみに、逆に join
と map
から、 bind
を作ることも出来る
purs(hs)bind :: m a -> (a -> m b) -> m b
bind x f = join $ map f x
参考