Oregon Programming Languages Summer School:
cs.uoregon.edu
Lecture Notes и тяжеловесные видео наличествуют.
Можно поглядеть на Пирса, Steve Awodey, Robert Harper, Xavier Leroy и John Hughes. И других товарищей из INRIA и CMU.
fmap' = fmap . fmap
pure' = pure . pure
(<>) = \f g → (<>) <> f <> g = liftA2 (<*>)
А в монадах никак:
join' :: Monad m,n ⇒ m (n (m (n a)) → m (n a)
Чтобы написать такую функцию необходимо иметь функцию swap :: Monad m,n ⇒ n (m a) → m (n a). В общем случае её написать нельзя. Для частных случаев, например двух Reader monads, можно. Осталось только понять каким законам должна подчиняться функция swap.
ErrorT String (Reader (EventAccessors e)) (Get (StateT e (Writer [DecodeError]) a))