Сами символы ничего не значат. Это произвольные имена, выбранные Хейко:
> class Foo[A, B]
defined class Foo
> class Foo[M1[_], M2[_]]
defined class Foo
> class GenericFunctor[->>[_, _], ->>>[_, _], F[_]]
defined class GenericFunctor
Они являются частями параметров типа, которые сами являются конструкторами типов (типы с более высоким родом, если вы хотите, чтобы это звучало модно).
Приложения типа могут быть написаны инфиксом, поэтому A ->> B
совпадает с ->>[A, B]
.
Что происходит ... Хайко говорит
Глядя на ингредиенты, мы находим все, что нам нужно: типы A
и B
отображаются на типы F[A]
и F[B]
, а карты A ->> B
отображаются на карты F[A] ->>> F[B]
.
Поскольку мы говорим о теории категорий, мы хотим избежать термина функция, потому что это зависит от реализации, но мы хотим описать что-то вроде функции. Нечто подобное функции в их жаргонном выражении - стрелка. Нам нужно два из них, так как мы не хотим, чтобы входящие и исходящие стрелки были одинаковыми. Эти две стрелки представлены ->>
и ->>>
. F[_]
- это контейнер типа List
и Option
. Я думаю ..
Итак, fmap
(он же метод map
в Scala) принимает стрелку значений и возвращает еще одну стрелку контейнеров. За исключением отличного от map
метода, fmap
возвращает стрелку, которая принимает контейнер.
Конкретное применение GenericFunctor
с использованием Function
для обеих стрелок - Functor
. И конкретное применение Functor
, которое использует List
для контейнера: ListFunctor
.
object ListFunctor extends Functor[List] {
def fmap[A, B](f: A => B): List[A] => List[B] = as => as map f
}
Итак, функция принимает значение от A
до B
и возвращает функцию от List[A]
до List[B]
, вызывая map
внутри.