Закон 1

Первый закон функторов гласит, что если мы применяем функцию id к значению функтора, то значение функтора, которое мы получим, должно быть таким же, как первоначальное значение функтора. В формализованной записи это выглядит так: fmap id = id. Иными словами, если мы применим fmap id к значению функтора, это должно быть то же самое, что и просто применение функции id к значению. Вспомните, что id – это функция тождества, которая просто возвращает свой параметр неизменным. Она также может быть записана в виде x –> x. Если воспринимать значение функтора как нечто, что может быть отображено, то закон fmap id = id представляется довольно очевидным.

Давайте посмотрим, выполняется ли он для некоторых значений функторов:

ghci> fmap id (Just 3)

Just 3

ghci> id (Just 3)

Just 3

ghci> fmap id [1..5]

[1,2,3,4,5]

ghci> id [1..5]

[1,2,3,4,5]

ghci> fmap id []

[]

ghci> fmap id Nothing

Nothing

Если посмотреть на реализацию функцию fmap, например, для типа Maybe, мы можем понять, почему выполняется первый закон функторов:

instance Functor Maybe where

   fmap f (Just x) = Just (f x)

   fmap f Nothing= Nothing

Мы представляем, что функция id играет роль параметра f в этой реализации. Нам видно, что если мы применяем fmap id к значению Just x, то результатом будет Just (id x), и поскольку id просто возвращает свой параметр, мы можем сделать вывод, что Just (id x) равно Just x. Теперь нам известно, что если мы применим функцию id к значению типа Maybe, созданному с помощью конструктора данных Just, обратно мы получим то же самое значение.

Видно, что применение функции id к значению Nothing возвращает то же самое значение Nothing. Поэтому из этих двух равенств в реализации функции fmap нам видно, что закон fmap id = id соблюдается.