All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spire.algebra.partial.Groupoid.scala Maven / Gradle / Ivy

The newest version!
package spire
package algebra
package partial

import spire.util.Opt
import spire.syntax.eq._

/** A groupoid is a semigroupoid where inverse are defined for all elements,
  * and thus left and right identity elements such that:
  *
  *   (i) (leftId(g) |+|? g).get === g
  *  (ii) (g |+|? rightId(g)).get === g
  * (iii) `a.inverse |+|? a` and `a |+|? a.inverse` are always defined
  *  (iv) if `a |+|? b`, then `((a |+|? b).get |+|? b.inverse).get === a` and
  *       `((a.inverse |+|? a).get |+|? b) === b`
  *
  */
trait Groupoid[A] extends Any with Semigroupoid[A] {
  /** Tests if `a` is an identity. */
  def isId(a: A)(implicit ev: Eq[A]): Boolean = a === leftId(a)
  /** Returns the inverse element of `a` such that `(a |+|? a.inverse).get` is an identity. */
  def inverse(a: A): A
  /** Returns the left identity of `a`. */
  def leftId(a: A): A = partialOp(a, inverse(a)).get
  /** Returns the right identity of `a`. */
  def rightId(a: A): A = partialOp(inverse(a), a).get
  def partialOpInverse(x: A, y: A): Opt[A] = partialOp(x, inverse(y))
  def opInverseIsDefined(x: A, y: A): Boolean = opIsDefined(x, inverse(y))
}

trait GroupoidLowPriority {
  implicit def fromGroup[A](implicit group: Group[A]): Groupoid[A] =
    new Groupoid[A] {
      override def opIsDefined(x: A, y: A): Boolean = true
      override def opInverseIsDefined(x: A, y: A): Boolean = true
      def inverse(a: A): A = group.inverse(a)
      def partialOp(x: A, y: A): Opt[A] = Opt(group.op(x, y))
      override def partialOpInverse(x: A, y: A): Opt[A] = Opt(group.opInverse(x, y))
    }
}

object Groupoid extends GroupoidLowPriority {
  @inline final def apply[A](implicit g: Groupoid[A]): Groupoid[A] = g
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy