Функторы возвращаются
Как вы узнали из главы 7, функторы – это сущности, которые можно отобразить, как, например, списки, значения типа Maybe и деревья. В языке Haskell они описываются классом типов Functor, содержащим только один метод fmap. Функция fmap имеет тип fmap :: (a –> b) –> f a –> f b, который говорит: «Дайте мне функцию, которая принимает a и возвращает b и коробку, где содержится a (или несколько a), и я верну коробку с b (или несколькими b) внутри». Она применяет функцию к элементу внутри коробки.
Мы также можем воспринимать значения функторов как значения с добавочным контекстом. Например, значения типа Maybe обладают дополнительным контекстом того, что вычисления могли окончиться неуспешно. По отношению к спискам контекстом является то, что значение может быть множественным либо отсутствовать. Функция fmap применяет функцию к значению, сохраняя его контекст.
Если мы хотим сделать конструктор типа экземпляром класса Functor, он должен иметь сорт * –> *; это значит, что он принимает ровно один конкретный тип в качестве параметра типа. Например, конструктор Maybe может быть сделан экземпляром, так как он получает один параметр типа для произведения конкретного типа, как, например, Maybe Int или Maybe String. Если конструктор типа принимает два параметра, как, например, конструктор Either, мы должны частично применять конструктор типа до тех пор, пока он не будет принимать только один параметр. Поэтому мы не можем написать определение Functor Either where, зато можем написать определение Functor (Either a) where. Затем, если бы мы вообразили, что функция fmap предназначена только для работы со значениями типа Either a, она имела бы следующее описание типа:
fmap :: (b –> c) –> Either a b –> Either a c
Как видите, часть Either a – фиксированная, потому что частично применённый конструктор типа Either a принимает только один параметр типа.