The concept of monoid homomorphism is useful for expressing a formal
semantics of iteration over collections. However, it is not very
convenient as a programming construct. A natural notation for such a
construct that is both conspicuous and can be expressed in terms of
monoid homomorphisms is a monoid comprehension. This notion
generalizes the familiar notation used for writing a set in comprehension
(as opposed to writing it in extension) using a pattern and a formula
describing its elements (as oppposed to listing all its elements). For
example, the set comprehension
describes the set of pairs
(the pattern),
verifying the formula
(the qualifier).
This notation can be extended to any (primitive or collection) monoid
. The syntax of a monoid comprehension is an expression of the
form
where
is an expression called the
head of the comprehension, and
is called its qualifier and is
a sequence
,
, where each
is either
As for semantics, the meaning of a monoid comprehension is defined in terms of monoid homomorphisms.
Although Definition 4.2 can be effectively computed using nested loops (i.e., using the iteration semantics (1)), such would be in general rather inefficient. Rather, an optimized implementation can be achieved by various syntactic transformation expressed as rewrite rules. Thus, the principal benefit of using monoid comprehensions is to formulate efficient optimizations on a simple and uniform general syntax of expressions irrespective of specific monoids.
Note that relational joins are immediately expressible as monoid
comprehensions. Indeed, the join of two sets
and
using a function
and a predicate
is simply:
Clearly, monoid comprehensions can immediately express queries using all usual relational operators (and, indeed, object queries as well) and most usual functions. For example,