К завтрашнему занятию задачку со звёздочкой сделал, а то некоторые больно умные последние 15 минут практики бьют баклуши, решив всё заданное.
Введём следующий трёхпараметрический типовый оператор, инкапсулирующий композицию однопараметрических конструкторов типов:
newtype Compose f g x = Compose {getCompose :: f (g x)}
Каков кайнд этого конструктора типов? Приведите пример замкнутого типа, сконструированного с помощью Compose, и пример терма этого типа.
Определите функцию
ffmap h = getCompose . fmap h . Compose
и объясните её выведенный тип. Попробуйте осуществить вызов
> ffmap (+42) $ Just [1,2,3]
В чём причина ошибки?
Чтобы обеспечить работоспособность подобного вызова, сделайте тип Compose представителем класса типов Functor:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap = ???
Проверьте работоспособность на примерах:
> ffmap (+42) $ Just [1,2,3]
Just [43,44,45]
> ffmap (+42) $ [Just 1,Just 2,Nothing]
[Just 43,Just 44,Nothing]
Сделайте тип Compose представителем класса типов Applicative:
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure = ???
(<*>) = ???
Проверьте работоспособность на примерах:
> getCompose $ (+) <$> Compose [Just 1,Just 2] <*> Compose [Nothing,Just 40]
[Nothing,Just 41,Nothing,Just 42]
> getCompose $ (+) <$> Compose [Just 1,Just 2] <*> Compose [Just 30,Just 40]
[Just 31,Just 41,Just 32,Just 42]
> getCompose $ Compose [[(+1)],[(+2),(+3)]] <*> Compose [[10,20],[]]
[[11,21],[],[12,22,13,23],[]]
Originally posted at
http://deniok.dreamwidth.org/50419.html. Feel free to comment here or there.