В вашем примере Functor
является endofunctor в категории типов Scala с Function1
в виде стрелок.
Существуют и другие категории.Например, представьте категорию, в которой объекты являются типами Scala, и есть стрелка A >~> B
, если B
является подтипом A
.Эта категория в Scalaz называется Liskov
.Существует «забывчивый» функтор из категории Liskov
в категорию Function1
:
import scalaz._
import Scalaz._
trait Forget[F[-_]] extends GenericFunctor[>~>, Function1, F] {
def fmap[A, B](f: A >~> B): F[A] => F[B] = fa => f.subst(fa)
}
Обратите внимание, что вы можете создать некоторые интересные функторы, зафиксировав один или несколько аргументов в GenericFunctor
.Например ...
A константный функтор отображает каждый объект в одной категории на один объект в другой:
type ConstantFunctor[->>[_, _], ->>>[_, _], C] =
GenericFunctor[->>,->>>,({type F[x] = C})#F]
// def fmap[A, B](f: A ->> B): C ->>> C
endofunctor сопоставляет категорию с самим собой:
type EndoFunctor[->>[_, _], F[_]] = GenericFunctor[->>, ->>, F]
// def fmap[A, B](f: A ->> B): F[A] ->> F[B]
функтор идентификации отображает каждый объект и стрелку на себя:
type IdentityFunctor[->>[_, _]] = EndoFunctor[->>, ({type F[x] = x})#F]
// def fmap[A, B](f: A ->> B): A ->> B
И, конечно, ваша Functor
чертаэто просто EndoFunctor
в категории Function1
.
type Functor[F[_]] = EndoFunctor[Function1, F]
// def fmap[A, B](f: A => B): F[A] => F[B]