Functors - Category Framework

Skip to content
Back to top
View this page
Edit this page

# Functors

AUTHORS:

- David Kohel and William Stein

- David Joyner (2005-12-17): examples

- Robert Bradshaw (2007-06-23): Pyrexify

- Simon King (2010-04-30): more examples, several bug fixes, re-implementation of the default call method, making functors applicable to morphisms (not only to objects)

- Simon King (2010-12): Pickling of functors without losing domain and codomain

sage.categories.functor.ForgetfulFunctor(domain, codomain)

  Construct the forgetful function from one category to another.

  INPUT:

  - `C`, `D` – two categories

  OUTPUT:

  A functor that returns the corresponding object of `D` for any element of `C`, by forgetting the extra structure.

  ASSUMPTION:

  The category `C` must be a sub-category of `D`.

  EXAMPLES:

  Sage

      sage: rings = Rings()
      sage: abgrps = CommutativeAdditiveGroups()
      sage: F = ForgetfulFunctor(rings, abgrps)
      sage: F
      The forgetful functor
       from Category of rings
         to Category of commutative additive groups

  Python

      >>> from sage.all import *
      >>> rings = Rings()
      >>> abgrps = CommutativeAdditiveGroups()
      >>> F = ForgetfulFunctor(rings, abgrps)
      >>> F
      The forgetful functor
       from Category of rings
         to Category of commutative additive groups

  It would be a mistake to call it in opposite order:

  Sage

      sage: F = ForgetfulFunctor(abgrps, rings)
      Traceback (most recent call last):
      ...
      ValueError: Forgetful functor not supported for domain
      Category of commutative additive groups

  [Python]

      >>> from sage.all import *
      >>> F = ForgetfulFunctor(abgrps, rings)
      Traceback (most recent call last):
      ...
      ValueError: Forgetful functor not supported for domain
      Category of commutative additive groups

  If both categories are equal, the forgetful functor is the same as the identity functor:

  Sage

      sage: ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps)
      True

  Python

      >>> from sage.all import *
      >>> ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps)
      True

class sage.categories.functor.ForgetfulFunctor_generic

  Bases: `Functor`

  The forgetful functor, i.e., embedding of a subcategory.

  NOTE:

  Forgetful functors should be created using `ForgetfulFunctor()`, since the init method of this class does not check whether the domain is a subcategory of the codomain.

  EXAMPLES:

  Sage

      sage: F = ForgetfulFunctor(FiniteFields(), Fields())  # indirect doctest
      sage: F
      The forgetful functor
       from Category of finite enumerated fields
         to Category of fields
      sage: F(GF(3))
      Finite Field of size 3

  Python

      >>> from sage.all import *
      >>> F = ForgetfulFunctor(FiniteFields(), Fields())  # indirect doctest
      >>> F
      The forgetful functor
       from Category of finite enumerated fields
         to Category of fields
      >>> F(GF(Integer(3)))
      Finite Field of size 3

class sage.categories.functor.Functor

  Bases: `SageObject`

  A class for functors between two categories.

  NOTE:

  - In the first place, a functor is given by its domain and codomain, which are both categories.

  - When defining a sub-class, the user should not implement a call method. Instead, one should implement three methods, which are composed in the default call method:

    - `_coerce_into_domain(self, x)` – return an object of `self`’s domain, corresponding to `x`, or raise a `TypeError`. - Default: Raise `TypeError` if `x` is not in `self`’s domain.

    - `_apply_functor(self, x)` – apply `self` to an object `x` of `self`’s domain. - Default: Conversion into `self`’s codomain.

    - `_apply_functor_to_morphism(self, f)` – apply `self` to a morphism `f` in `self`’s domain. - Default: Return `self(f.domain()).hom(f,self(f.codomain()))`.

  EXAMPLES:

  Sage

      sage: rings  = Rings()
      sage: abgrps = CommutativeAdditiveGroups()
      sage: F = ForgetfulFunctor(rings, abgrps)
      sage: F.domain()
      Category of rings
      sage: F.codomain()
      Category of commutative additive groups
      sage: from sage.categories.functor import Functor
      sage: isinstance(F, Functor)
      True
      sage: I = IdentityFunctor(abgrps)
      sage: I
      The identity functor on Category of commutative additive groups
      sage: I.domain()
      Category of commutative additive groups
      sage: isinstance(I, Functor)
      True

  Python

      >>> from sage.all import *
      >>> rings  = Rings()
      >>> abgrps = CommutativeAdditiveGroups()
      >>> F = ForgetfulFunctor(rings, abgrps)
      >>> F.domain()
      Category of rings
      >>> F.codomain()
      Category of commutative additive groups
      >>> from sage.categories.functor import Functor
      >>> isinstance(F, Functor)
      True
      >>> I = IdentityFunctor(abgrps)
      >>> I
      The identity functor on Category of commutative additive groups
      >>> I.domain()
      Category of commutative additive groups
      >>> isinstance(I, Functor)
      True

  Note that by default, an instance of the class Functor is coercion from the domain into the codomain. The above subclasses overloaded this behaviour. Here we illustrate the default:

  Sage

      sage: from sage.categories.functor import Functor
      sage: F = Functor(Rings(), Fields())
      sage: F
      Functor from Category of rings to Category of fields
      sage: F(ZZ)
      Rational Field
      sage: F(GF(2))
      Finite Field of size 2

  [Python]

      >>> from sage.all import *
      >>> from sage.categories.functor import Functor
      >>> F = Functor(Rings(), Fields())
      >>> F
      Functor from Category of rings to Category of fields
      >>> F(ZZ)
      Rational Field
      >>> F(GF(Integer(2)))
      Finite Field of size 2

  Functors are not only about the objects of a category, but also about their morphisms. We illustrate it, again, with the coercion functor from rings to fields.

  Sage

      sage: R1.<x> = ZZ[]
      sage: R2.<a,b> = QQ[]
      sage: f = R1.hom([a + b], R2)
      sage: f
      Ring morphism:
        From: Univariate Polynomial Ring in x over Integer Ring
        To:   Multivariate Polynomial Ring in a, b over Rational Field
        Defn: x |--> a + b
      sage: F(f)
      Ring morphism:
        From: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
        To:   Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field
        Defn: x |--> a + b
      sage: F(f)(1/x)
      1/(a + b)

  Python

      >>> from sage.all import *
      >>> R1 = ZZ['x']; (x,) = R1._first_ngens(1)
      >>> R2 = QQ['a, b']; (a, b,) = R2._first_ngens(2)
      >>> f = R1.hom([a + b], R2)
      >>> f
      Ring morphism:
        From: Univariate Polynomial Ring in x over Integer Ring
        To:   Multivariate Polynomial Ring in a, b over Rational Field
        Defn: x |--> a + b
      >>> F(f)
      Ring morphism:
        From: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
        To:   Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field
        Defn: x |--> a + b
      >>> F(f)(Integer(1)/x)
      1/(a + b)

  We can also apply a polynomial ring construction functor to our homomorphism. The result is a homomorphism that is defined on the base ring:

  Sage

      sage: F = QQ['t'].construction()[0]
      sage: F
      Poly[t]
      sage: F(f)
      Ring morphism:
        From: Univariate Polynomial Ring in t
               over Univariate Polynomial Ring in x over Integer Ring
        To:   Univariate Polynomial Ring in t
               over Multivariate Polynomial Ring in a, b over Rational Field
        Defn: Induced from base ring by
              Ring morphism:
                From: Univariate Polynomial Ring in x over Integer Ring
                To:   Multivariate Polynomial Ring in a, b over Rational Field
                Defn: x |--> a + b
      sage: p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1')
      sage: F(f)(p)
      (-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t
      - 4*a^2 - 8*a*b - 4*b^2 - a - b + 1

  [Python]

      >>> from sage.all import *
      >>> F = QQ['t'].construction()[Integer(0)]
      >>> F
      Poly[t]
      >>> F(f)
      Ring morphism:
        From: Univariate Polynomial Ring in t
               over Univariate Polynomial Ring in x over Integer Ring
        To:   Univariate Polynomial Ring in t
               over Multivariate Polynomial Ring in a, b over Rational Field
        Defn: Induced from base ring by
              Ring morphism:
                From: Univariate Polynomial Ring in x over Integer Ring
                To:   Multivariate Polynomial Ring in a, b over Rational Field
                Defn: x |--> a + b
      >>> p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1')
      >>> F(f)(p)
      (-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t
      - 4*a^2 - 8*a*b - 4*b^2 - a - b + 1

  codomain()

    The codomain of `self`.

    EXAMPLES:

    Sage

        sage: F = ForgetfulFunctor(FiniteFields(), Fields())
        sage: F.codomain()
        Category of fields

    Python

        >>> from sage.all import *
        >>> F = ForgetfulFunctor(FiniteFields(), Fields())
        >>> F.codomain()
        Category of fields

  domain()

    The domain of `self`.

    EXAMPLES:

    Sage

        sage: F = ForgetfulFunctor(FiniteFields(), Fields())
        sage: F.domain()
        Category of finite enumerated fields

    Python

        >>> from sage.all import *
        >>> F = ForgetfulFunctor(FiniteFields(), Fields())
        >>> F.domain()
        Category of finite enumerated fields

sage.categories.functor.IdentityFunctor(C)

  Construct the identity functor of the given category.

  INPUT:

  - `C` – a category

  OUTPUT: the identity functor in `C`

  EXAMPLES:

  Sage

      sage: rings = Rings()
      sage: F = IdentityFunctor(rings)
      sage: F(ZZ['x','y']) is ZZ['x','y']
      True

  Python

      >>> from sage.all import *
      >>> rings = Rings()
      >>> F = IdentityFunctor(rings)
      >>> F(ZZ['x','y']) is ZZ['x','y']
      True

class sage.categories.functor.IdentityFunctor_generic(C)

  Bases: `ForgetfulFunctor_generic`

  Generic identity functor on any category.

  NOTE:

  This usually is created using `IdentityFunctor()`.

  EXAMPLES:

  Sage

      sage: F = IdentityFunctor(Fields()) #indirect doctest
      sage: F
      The identity functor on Category of fields
      sage: F(RR) is RR
      True
      sage: F(ZZ)
      Traceback (most recent call last):
      ...
      TypeError: x (=Integer Ring) is not in Category of fields

  Python

      >>> from sage.all import *
      >>> F = IdentityFunctor(Fields()) #indirect doctest
      >>> F
      The identity functor on Category of fields
      >>> F(RR) is RR
      True
      >>> F(ZZ)
      Traceback (most recent call last):
      ...
      TypeError: x (=Integer Ring) is not in Category of fields