Когда я изучал главу " Composing Types
из книги "Haskell", мне дали задание написать экземпляры Functor и Applicative для следующего типа.
newtype Compose f g a = Compose { getCompose :: f (g a) }
Я написал следующие определения
Функтор:
fmap f (Compose fga) = Compose $ (fmap . fmap) f fga
Прикладное:
(Compose f) <*> (Compose a) = Compose $ (<*>) <$> f <*> a
Я узнал, что составление двух Функторов или Аппликативов дает Функтор и Аппликатив соответственно.
Автор также объяснил, что невозможно составить две монады одинаково. Поэтому мы используем монадные трансформаторы. Я просто не хочу читать Монадные Трансформеры, если не понимаю, почему Монады не сочиняют.
До сих пор я пытался написать функцию bind
следующим образом:
Монада:
(>>=) :: Compose f g a -> (a -> Compose f g b) -> Compose f g b
(Compose fga) >>= h = (fmap.fmap) h fga
и, конечно, получил эту ошибку от GHC
Ожидаемый тип: составить FGB
Фактический тип: f (g (Compose fgb))
Если я смогу как-нибудь лишить fg
, композиция даст нам монаду, верно? (Я все еще не мог понять, как раздеть это все же)
Я попытался прочитать ответы на другие вопросы о переполнении стека, как это, но все ответы более теоретические или математические. Я до сих пор не понял, почему монады не сочиняют. Может кто-нибудь объяснить мне без использования математики?