и
>b
должны конкретизироваться одним и тем же типом. Если попытаться применить функцию, которая принимает строку и возвращает строку, то
>b
у нас – строка, а
>a
– число; это не сработает. Также, когда мы смотрели на тип функции
>fmap
для типа
>Either a
, то видели, что первый параметр не изменяется, а второй может быть изменён; первый параметр актуализируется конструктором данных
>Left
.
Здесь можно продолжить нашу аналогию с коробками, представив часть >Left
как пустую коробку, на которой сбоку записано сообщение об ошибке, поясняющее, почему внутри пусто.
Отображения из модуля >Data.Map
также можно сделать функтором, потому что они хранят (или не хранят) значения. Для типа >Map k v
функция >fmap
будет применять функцию >v –> v'
на отображении типа >Map k v
и возвращать отображение типа >Map
>k
>v'
.
ПРИМЕЧАНИЕ. Обратите внимание: апостроф не имеет специального значения в типах (как не имеет его и в именовании значений). Этот символ используется для обозначения схожих понятий, незначительно отличающихся друг от друга.
Попытайтесь самостоятельно догадаться, как для типа >Map k
определён экземпляр класса >Functor
!
На примере класса типов >Functor
мы увидели, что классы типов могут представлять довольно мощные концепции высокого порядка. Также немного попрактиковались в частичном применении типов и создании экземпляров. В одной из следующих глав мы познакомимся с законами, которые должны выполняться для функторов.