% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/30-api-flexseq-measure-monoid.R
\name{measure_monoid}
\alias{measure_monoid}
\title{Construct a Measure Monoid Specification}
\usage{
measure_monoid(f, i, measure)
}
\arguments{
\item{f}{Associative binary function over measure values.}

\item{i}{Identity value for \code{f}.}

\item{measure}{Function mapping one element to its measure value.}
}
\value{
An object of class \code{measure_monoid}.
}
\description{
Defines how element-level values are measured and combined as accumulated
tree metadata.
}
\details{
A measure monoid has three parts:
\itemize{
\item \code{measure(entry)}: maps each stored leaf entry to a measure value.
\item \code{f(left, right)}: combines two measure values.
\item \code{i}: identity value for \code{f}.
}

Requirements:
\itemize{
\item \code{f} should be associative.
\item \code{i} should satisfy \code{f(i, x) == x} and \code{f(x, i) == x}.
\item \code{measure()} outputs must be compatible with \code{f} and \code{i}.
}

Developer APIs are leaf-entry oriented:
\itemize{
\item \code{flexseq}: entry is the stored user element.
\item \code{ordered_sequence}: entry is \code{list(value, key)}.
\item \code{priority_queue}: entry is \code{list(value, priority)}.
\item \code{interval_index}: entry is \code{list(value, start, end)}.
}

\code{measure_monoid()} only constructs the specification; it becomes active after
being attached to a structure via \code{\link[=add_monoids]{add_monoids()}}.
}
\examples{
sum_m <- measure_monoid(`+`, 0, as.numeric)
x <- as_flexseq(1:5)
x2 <- add_monoids(x, list(sum = sum_m))
attr(x2, "measures")$sum
split_around_by_predicate(x2, function(v) v >= 6, "sum")

# Count elements
count_m <- measure_monoid(`+`, 0L, function(el) 1L)
x3 <- add_monoids(x, list(count = count_m))
attr(x3, "measures")$count

# Character-width accumulation
width_m <- measure_monoid(`+`, 0L, function(el) nchar(as.character(el)))
s <- as_flexseq(c("aa", "b", "cccc"))
s2 <- add_monoids(s, list(width = width_m))
attr(s2, "measures")$width
}
