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

algebra.Monoid.scala Maven / Gradle / Ivy

There is a newer version: 0.4.2
Show newest version
package algebra

import scala.{ specialized => sp }

/**
 * A monoid is a semigroup with an identity. A monoid is a specialization of a
 * semigroup, so its operation must be associative. Additionally,
 * `combine(x, empty) == combine(empty, x) == x`. For example, if we have `Monoid[String]`,
 * with `combine` as string concatenation, then `empty = ""`.
 */
trait Monoid[@sp(Int, Long, Float, Double) A] extends Any with Semigroup[A] {

  /**
   * Return the identity element for this monoid.
   */
  def empty: A

  /**
   * Tests if `a` is the identity.
   */
  def isEmpty(a: A)(implicit ev: Eq[A]) = ev.eqv(a, empty)

  /**
   * Return `a` appended to itself `n` times.
   */
  override def combineN(a: A, n: Int): A =
    if (n < 0) throw new IllegalArgumentException("Repeated combining for monoids must have n >= 0")
    else if (n == 0) empty
    else repeatedCombineN(a, n)

  /**
   * Given a sequence of `as`, sum them using the monoid and return the total.
   */
  def combineAll(as: TraversableOnce[A]): A =
    as.foldLeft(empty)(combine)
}

trait MonoidFunctions extends SemigroupFunctions {
  def empty[@sp(Int, Long, Float, Double) A](implicit ev: Monoid[A]): A =
    ev.empty

  def combineAll[@sp(Int, Long, Float, Double) A](as: TraversableOnce[A])(implicit ev: Monoid[A]): A =
    ev.combineAll(as)
}

object Monoid extends MonoidFunctions {

  /**
   * Access an implicit `Monoid[A]`.
   */
  @inline final def apply[A](implicit ev: Monoid[A]): Monoid[A] = ev

  /**
   * This method converts an additive instance into a generic
   * instance.
   * 
   * Given an implicit `AdditiveMonoid[A]`, this method returns a
   * `Monoid[A]`.
   */
  @inline final def additive[A](implicit ev: ring.AdditiveMonoid[A]): Monoid[A] =
    ev.additive

  /**
   * This method converts an multiplicative instance into a generic
   * instance.
   * 
   * Given an implicit `MultiplicativeMonoid[A]`, this method returns
   * a `Monoid[A]`.
   */
  @inline final def multiplicative[A](implicit ev: ring.MultiplicativeMonoid[A]): Monoid[A] =
    ev.multiplicative
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy