Реализация представителя Functor для двухпараметрических типов

Двухпараметрические типы: Either, пара. Они требуют двух типовых параметров.

Класс типов Functor в качестве своего типового параметра требует переменной, которая имеет один типовой параметр. Это проблема решается следующим образом, можно взять и связать один из этих параметров каким-то значением и после этого наш тип становится однопараметрическим. 

Например тип Either Int это тип у которого один параметр. В левой ветви у него содержится Int, а в правой что-то с типом параметра.


Пара со связанным первым параметром:
Prelude> :k (,)
(,) :: * -> * -> *
Prelude> :k (,) Int
(,) Int :: * -> *
Представитель класса типов Functor для пары:
Первый элемент пары имеет произвольный тип s. Функция fmap может работать только со вторым элементом пары.
Prelude> fmap succ (1,'A')
(1,'B')


Реализация представителя Functor для типа данных Either:
С типом e мы ничего делать не можем. Тип e этот тот тип, который хранится в конструкторе Left. А типы a и b будут храниться соответственно в конструкторе Right. Тип e недоступен потому что у нас нет по типам инструментов чтобы что-то изменять. У нас есть единственный инструмент функция g, но она как раз будет работать в конструкторе Right.
Prelude> fmap (+3) $ Right 1
Right 4
Prelude> fmap (+3) $ Left 1
Left 1
Prelude> fmap (+3) $ Left "AAA"
Left "AAA"
В паре лежит и то, и другое, а в типе данных Either лежит либо то, либо другое.


Функциональная стрелка со связанным первым параметром:
Prelude> :k (->)
(->) :: * -> * -> *
Prelude> :k (->) Int
(->) Int :: * -> *
Реализация представителя Functor для функциональной стрелочки:
Пример:
Prelude> :t fmap length tail
fmap length tail :: [a] -> Int



Prelude> fmap length tail "ABC"
2
Когда тип функции становится полиморфным по возвращаемому значению, то арность функции может нарастать.

На основе частично примененной функциональной стрелочки делается одна из монад.


Определение представителя класса Functor для типов данных Entry и Map.