Category

Формальное определение

Category - это Compose с операцией identity. Category можно трансформировать в Monoid и PlusEmpty.

Category должен удовлетворять следующим законам (помимо законов родительских классов типов):

Тождественность

Каждый объект имеет специальную стрелку, называемую тождественной (или тождественностью), которая оставляет объект неизменным. Это означает, что когда вы компонуете тождественную стрелку с любой другой стрелкой, входящей или исходящей, то получаете ту же стрелку. Тождественная стрелка ничего не делает с другой стрелкой.

Тождественная стрелка на объекте a обозначается как \(id_{a}\). Так что, если имеется стрелка \(f : a \to b\), то можно скомпоновать ее с тождественностями с обеих сторон: \(id_{b} \circ f = f = f \circ id_{a}\)

Возьмем элемент \(x : 1 \to a\) и скомпонуем его с \(id_{a}\). Результат \(id_{a} \circ x = x\) означает, что тождественность оставляет элементы неизменными.

Определение в виде кода на Scala

trait Category[=>:[_, _]] extends Compose[=>:]:
  def id[A]: A =>: A

  def empty: PlusEmpty[[A] =>> A =>: A] = new PlusEmpty[[A] =>> A =>: A] with ComposePlus:
    def empty[A]: A =>: A = id

  def monoid[A]: Monoid[A =>: A] = new Monoid[A =>: A] with ComposeSemigroup[A]:
    def empty: A =>: A = id

Примеры

Функция от одной переменной

given Category[Function1] with
  override def compose[A, B, C](f: B => C, g: A => B): A => C = g andThen f

  override def id[A]: A => A = a => a

Реализация

Реализация в ScalaZ

import scalaz.*
import Scalaz.*

// ... Все операции родителей

Ссылки: