data MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)}
data ReaderT r m a = ReaderT {runReaderT :: r -> m a}

인데, 보다시피 MaybeT는 Maybe 다음에 m을 적용하고, ReaderT는 m다음에 ((->) r)을 적용함.
원래 여기에 별 생각이 없었는데, 누가 질문을 해서 좀 생각해봄.

모나드 M하고 T가 있다고 하자. 이 두 모나드의 합성 MT가 모나드이려면
μ : MTMT -> MT
가 존재하고, μ가 모나드 법칙을 만족해야함. (μ가 join임)


그런데 flip : TM -> MT가 존재한다면 이걸로 μ를 유도할 수 있음 (모나드 법칙은 보장 안됨)
* 카테고리 이론에서 쓰는 문법 규칙을 잘 모르니 대충 느낌으로 이해하셈. 잘 아는 사람 있으면 확인좀
μ = M(μ_T) . μ_M . M(flip) = μ_M . M(M(μ_T)) . M(flip)

여기서
μ_M : MM -> M
μ_T : TT -> T


다이어그램으로 그려보면
MTMT
|
|
MMTT ----------> MMT
|                              |
|                              |
MTT----‐-----------> MT
이런 느낌

그러니까 사이에 끼어있는 TM을 MT로 바꿔주는 flip이 있으면, 안쪽하고 바깥쪽에 각각 M과 T의 join을 적용해서 MT의 join을 얻을 수 있다는 말임.

여기서 flip을 하스켈 식으로 써보면
flip :: t (m a) -> m (t a)
인데, 하스켈에 flip을 가진 클래스가 2개 있음

sequence :: (Traversable t, Applicative m) => t (m a) -> m (t a)
하고
distribute :: (Functor t, Distributive m) => t (m a) -> m (t a)
임. Distributive Functor는 표준 라이브러리에는 없는데 hackage에 있음.

그래서 Traversable하고 Distributive에서 2가지 종류의 monad transformer를 유도할 수 있음.
data TransT t m a = TransT {runTransT :: m (t a)}
data TransD m t a = TransD {runTransD :: m (t a)}
TransT는 Traversable t가 있을 때 모든 Monad m에 대해 Monad (TransT t m)을 가지고, TransD는 Distributive m이 있을 때 모든 Monad t에 대해 Monad (TransD m t)를 가짐.

여기에 Traversable Maybe하고 Distributive ((->) r) 을 대입해보면 MaybeT하고 ReaderT 를 얻을 수 있음.

이것 때문에 MaybeT하고 ReaderT에 인자 적용순서가 다른거. Maybe는 Traversable이고, ((->) r)은 Distributive라서.

그래서 IdentityT m a 는 m (Identity a)도 되고, Identity (m a)도 됨. Identity는 Traversable이면서 Distributive거든. 물론 둘다 그냥 m a랑 같아서 별 의미는 없음