圏論においてモナドの定義に2つ方法があるのと同様に,関数型言語においても2つの定義がある.
joinとunitによる定義あるデータ型M aがモナドであるとは,
unit :: a -> M a join :: M (M a) -> M a map :: (a -> b) -> M a -> M b
という関数に対し,
map id = idM(関手)map (f.g) = map f . map g(関手)map f . unit = unit . f(unitは自然変換)map f . join = join . map (map f)(joinは自然変換)join . unit = idMjoin . map unit = idMという性質を満たすことである.
bindによる定義あるデータ型M aがモナドであるとは,
unit :: a -> M a bind :: M a -> (a -> M b) -> M b
という関数に対し,
m `bind` unit = m unit a `bind` f = f a(m `bind` f) `bind` g = m `bind` (λx. f x `bind` g)という性質を満たすことである.
とうぜんこれらは相互に変換しあう.
m `bind` k = join (map k m)
であり,
map f m = m `bind` λx. unit (f x) join z = z `bind` id
である.
モナドは関数合成に通常と異なる意味を与えたものである.実際に f @ g = λx . f x `bind` gと定義すると,unitをid関数として, a -> M bという関数(モナディック関数とよばれる)の世界において,演算子@は関数合成のように振舞う.