Effect Schema Lifting¶
class_directed_lifts(base_schema, effect) and
lift_rule_set(base_schemas, effects) emit lifted SchemaDecls for
the typeclasses inhabited by an effect.
effect_lifts
¶
Class-driven schema lifting for effect-typed parsers.
The class_directed_lifts function takes a base
SchemaDecl and an effect instance and returns a tuple of
lifted SchemaDecl instances, one per typeclass-class the
effect inhabits.
The dispatch key is the typeclass interface, never the effect's
concrete identity. Adding a new effect (or a new typeclass) extends
the lifting machinery automatically: every effect that registers
against Functor gets fmap lifts; every effect that
additionally registers against Applicative also gets
apply lifts; every Monad gets bind lifts; and so
on across both the monad-style and arrow-style towers.
The lifted schemas are SchemaDecl instances and feed into
the same PatternBinarySchema / PatternUnarySchema
machinery as user-written schemas; the chart-fixed-point machinery in
quivers.stochastic.parsers consumes them uniformly with the
base schemas. The chart cells are indexed by (Cat, EffectStack)
pairs, and at each cell the parser fires:
- Base schemas between effect-pure cells (the classical Lambek case).
- Lift schemas when one or more children carry effect prefixes
that the schema's domain doesn't (this is what
class_directed_liftsproduces). - Handler firings when an applicable handler is registered, reducing an effect-typed cell to a less-effect-typed cell.
- Commutation firings when a registered distributive law swaps sibling effect orderings.
References
- Bumford, D. and Charlow, S. (2026). Effect-Driven Interpretation: Functors for Natural Language Composition. Cambridge Elements in Semantics. Cambridge University Press. Online ISBN 9781009285377; preprint arXiv:2504.00316.
class_directed_lifts
¶
class_directed_lifts(base_schema: SchemaDecl, effect: object) -> tuple[SchemaDecl, ...]
Generate the class-driven lifts for base_schema under effect.
Dispatches on which typeclasses the effect inhabits (Functor,
Applicative, Monad, Alternative, MonadPlus, ArrowApply, ArrowLoop,
and so on) and emits one or more SchemaDecl instances
per class. The lifts compose with the base schema in the chart
parser's joint type-and-effect dispatch.
Lifts emitted (when the corresponding class is inhabited):
Applicative:pure_T+apply_T.Monad(andApplicative): addsbind_T.Alternative: addsalt_T.MonadPlus: union of Monad and Alternative lifts.
Functor-only effects produce pure_T-shape lifts only when the
instance also implements Applicative; bare Functor
instances need a separate fmap_T shape (analogous to
apply_T but with one functor-typed premise rather than two).
Arrow-side lifts (arr_T, first_T, loop_T) are emitted
by a parallel branch that introspects the effect's arrow-tower
membership; see the # arrow lifts block below.
| PARAMETER | DESCRIPTION |
|---|---|
base_schema
|
The base schema being lifted.
TYPE:
|
effect
|
An effect instance (any class registered against the relevant
typeclass ABCs in
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple of SchemaDecl
|
Zero or more lifted schemas, ordered from weakest typeclass (Applicative) through strongest (MonadPlus + ArrowApply + ArrowLoop). |
Source code in src/quivers/stochastic/effect_lifts.py
make_swap_schema
¶
make_swap_schema(distributive_law: object, base_schema: SchemaDecl | None = None) -> SchemaDecl
Generate a swap_TU schema from a registered distributive law.
Given a DistributiveLaw λ : S ∘ T ⇒ T ∘ S, the chart
parser uses swap_TU to exchange sibling effect orderings at a
cell whose effect stack ends in T·U:
swap_TU[X : Cat] : T(U(X)) -> U(T(X))
The schema is consumed by the chart's commutation firing rule of Effects §4.4.
| PARAMETER | DESCRIPTION |
|---|---|
distributive_law
|
The law whose outer and inner monads the schema exchanges.
TYPE:
|
base_schema
|
The schema whose name the swap schema's name extends; the
name
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
SchemaDecl
|
The |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If |
Source code in src/quivers/stochastic/effect_lifts.py
swap_rule_set
¶
swap_rule_set(distributive_laws: tuple[object, ...]) -> tuple[SchemaDecl, ...]
Generate one swap_TU schema per registered distributive law.
The resulting tuple is appended to the chart parser's rule set alongside the class-driven lifts; the chart's commutation-firing dispatch picks each swap schema up by name.
| PARAMETER | DESCRIPTION |
|---|---|
distributive_laws
|
The registered distributive laws.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple of SchemaDecl
|
One swap schema per law, in the order given. |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If an entry is not a |
Source code in src/quivers/stochastic/effect_lifts.py
lift_rule_set
¶
lift_rule_set(base_schemas: tuple[SchemaDecl, ...], effects: tuple[object, ...]) -> tuple[SchemaDecl, ...]
Apply class_directed_lifts over a rule-set and effect-stack.
Returns the union of base schemas and all lifts produced for each (base_schema, effect) pair. The chart parser consumes the resulting tuple directly.
| PARAMETER | DESCRIPTION |
|---|---|
base_schemas
|
The base rule set.
TYPE:
|
effects
|
The effect instances to lift each base schema under.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple of SchemaDecl
|
The base schemas followed by every lift, grouped by base schema and then by effect. |