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

libretto.scaletto.impl.Blueprint.scala Maven / Gradle / Ivy

The newest version!
package libretto.scaletto.impl

import phantoms.*

/** A representation of Libretto functions. Unlike [[-⚬]], it is a proper blueprint
 * in that it does not exploit cycles in the (Scala-level) object graph.
 */
enum Blueprint[A, B]:
  case Regular(value: Fun[Blueprint, A, B])

  case FunRef(
    id: Object, // XXX: use a proper Id type
    f: Blueprint[A, B],
  )

  case ConstSub[A, B](
    f: Blueprint[A, B],
  ) extends Blueprint[One, Sub[A, B]]

  private[impl] lazy val sizeAndRefs: SizeAndRefs =
    import SizeAndRefs.one

    this match
      case FunRef(id, f) =>
        SizeAndRefs(1, Map(id -> f))
      case ConstSub(f) =>
        one + f.sizeAndRefs
      case Regular(f) =>
        one + f.foldMonoid([X, Y] => (g: Blueprint[X, Y]) => g.sizeAndRefs)

private[impl] case class SizeAndRefs(size: Long, refs: Map[Object, Blueprint[?, ?]]):
  def +(that: SizeAndRefs): SizeAndRefs =
    SizeAndRefs(this.size + that.size, this.refs ++ that.refs)

  def +(n: Int): SizeAndRefs =
    SizeAndRefs(size + n, refs)

private[impl] object SizeAndRefs {
  def apply(n: Int): SizeAndRefs =
    SizeAndRefs(n, Map.empty)

  val one: SizeAndRefs =
    SizeAndRefs(1)

  given Monoid[SizeAndRefs] with
    override def unit: SizeAndRefs = SizeAndRefs(0, Map.empty)
    override def combine(l: SizeAndRefs, r: SizeAndRefs): SizeAndRefs = l + r
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy