((,) e)
не является классом типа; это просто тип. И действительно, это является секционированным кортежем. Идея здесь в том, что вы можете думать о (e, a)
как о «контейнере», содержащем значение типа a
и «аннотацию» типа e
. fmap
для ((,) e)
изменяет значения , но не аннотации . В аналогии «функтор как контейнер» аннотация является частью контейнера , а не частью его содержимого .
Давайте рассмотрим сорт дерева:
data Tree f a
= Leaf
| Node (Tree f a) (f a) (Tree f a)
instance Functor f => Functor (Tree f) where
fmap _ Leaf = Leaf
fmap f (Node l fa r) = Node (fmap f l) (fmap f fa) (fmap f r)
Как они выглядят? Tree Identity a
- это простое двоичное дерево элементов типа a
. Он может представлять собой, например, набор значений. Tree ((,) k) a
, с другой стороны, является двоичным деревом из пар . Он может представлять карту от ключей типа k
до значений типа a
. Отображение дерева с помощью fmap
изменит значения, но оставит ключи в покое.