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

spire.algebra.free.FreeMonoid.scala Maven / Gradle / Ivy

The newest version!
package spire
package algebra
package free

final class FreeMonoid[A] private (val terms: List[A]) extends AnyVal { lhs =>

  /**
   * Map each term to type `B` and sum them using `B`'s [[Semigroup]],
   * as long as there is at least 1 term. Otherwise, return `None`.
   */
  def runSemigroup[B](f: A => B)(implicit B: Semigroup[B]): Option[B] =
    terms match {
      case head :: tail =>
        Some(tail.foldLeft(f(head)) { (acc, a) => B.op(acc, f(a)) })
      case Nil =>
        None
    }

  /**
   * Map each term to type `B` and sum them using `B`'s [[Monoid]].
   */
  def run[B](f: A => B)(implicit B: Monoid[B]): B =
    terms.foldLeft(B.id) { (acc, a) => B.op(acc, f(a)) }

  def |+|(rhs: FreeMonoid[A]): FreeMonoid[A] =
    new FreeMonoid(lhs.terms ::: rhs.terms)

  override def toString: String =
    terms.mkString(" |+| ")
}

object FreeMonoid { companion =>
  final def id[A]: FreeMonoid[A] = new FreeMonoid(Nil)

  final def apply[A](a: A): FreeMonoid[A] = lift(a)
  final def lift[A](a: A): FreeMonoid[A] = new FreeMonoid[A](a :: Nil)

  implicit def FreeMonoidMonoid[A]: Monoid[FreeMonoid[A]] = new Monoid[FreeMonoid[A]] {
    def id: FreeMonoid[A] = companion.id
    def op(a: FreeMonoid[A], b: FreeMonoid[A]): FreeMonoid[A] = a |+| b
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy