cove

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: MIT Imports: 1 Imported by: 0

README

Go Reference Go Report Card Coverage Status

English | 简体中文 | Español | 日本語 | Français

cove

Context layer for carrying explicit ambient context across kont suspension boundaries in Go.

Overview

When an external runtime such as a proactor, event loop, or dispatcher steps through kont suspensions one at a time, each suspended operation may need state that lives outside the operation itself: dispatch budget, ring capabilities, protocol phase, buffer-group validity. Without explicit context carriers, that state ends up in ad-hoc side maps or implicit globals that break composition.

cove pairs ambient context with values and suspensions so the context travels across asynchronous stepping boundaries as typed, composable data.

_, sv := cove.StepExprWith(Runtime{Budget: 8}, computation)
for sv.Suspension != nil {
    result := dispatch(sv.Ask(), sv.Op())
    _, sv = sv.ResumeWith(result, func(r Runtime) Runtime {
        r.Budget--
        return r
    })
}

The package is policy-free: it carries and checks context, but never schedules, retries, or dispatches.

Installation

go get code.hybscloud.com/cove

Requires Go 1.26+.

Core Types

Type Purpose
View[C, A] Comonadic carrier: value A under ambient context C
SuspensionView[C, A] kont suspension paired with ambient context
Req[C] Contravariant predicate over C (closure form): func(C) bool
ReqExpr[C] Contravariant predicate over C (defunctionalized form)
Rule[C] / RuleExpr[C] Named predicate with diagnostic Report
Checked[C, A] / CheckedExpr[C, A] Value gated by a requirement
Guarded[C, A] / GuardedExpr[C, A] Value gated by a named rule

Ambient constrains context type parameters (C, D). Focus constrains value type parameters (A, B).

Contextual Stepping

StepWith and StepExprWith evaluate a kont computation and pair its first suspension with ambient context. Each suspension is affine: consume it exactly once, via Resume, ResumeWith, or Discard.

val, sv := cove.StepExprWith(ctx, expr)
for sv.Suspension != nil {
    op := sv.Op()
    result := handle(op)
    val, sv = sv.Resume(result)
}

ResumeWith evolves the carried context between steps. For example, it can decrement budget, update capabilities, or advance protocol phase:

val, sv = sv.ResumeWith(result, func(r Runtime) Runtime {
    r.Budget--
    return r
})

MapContextSuspension and WithContextSuspension transport or replace the context carried on an already observed suspension, without changing the current suspension frontier:

sv = cove.MapContextSuspension(sv, func (r Runtime) Runtime {
r.Budget += 4
return r
})
sv = cove.WithContextSuspension(sv, Runtime{Budget: 16})

Once the computation completes, sv.Suspension becomes nil, but sv.Ask() still returns the carried context.

ObserveSuspension attaches ambient context to an existing kont.Suspension without performing any requirement check. CheckSuspension and CheckSuspensionExpr provide gated forms:

sv, ok := cove.CheckSuspension(runtime, susp, func(r Runtime) bool {
    return r.Budget > 0
})
if !ok {
    susp.Discard()
    return
}
result := dispatch(sv.Ask(), sv.Op())
val, sv = sv.Resume(result)
exprReq := cove.ExprAtom(func(r Runtime) bool { return r.Budget > 0 })
sv, ok := cove.CheckSuspensionExpr(runtime, susp, exprReq)
if !ok {
    susp.Discard()
    return
}
result := dispatch(sv.Ask(), sv.Op())
val, sv = sv.Resume(result)

Step and StepExpr re-export kont's evaluators without context binding.

Commands

Cmd[C, A, B] is a contextual command View[C, A] -> B. Run applies a command to a concrete View; ExtractCmd is the identity command; LiftCmd lifts a focus-only map into the contextual world; Compose composes commands through Extend.

cmd := cove.Compose(
func (v cove.View[Runtime, int]) string {
return fmt.Sprintf("budget=%d value=%d", v.Ask().Budget, v.Extract())
},
cove.LiftCmd(func (n int) int { return n + 1 }),
)
out := cove.Run(cove.Observe(Runtime{Budget: 8}, 41), cmd)
_ = out // "budget=8 value=42"

Requirements

Requirements are predicates over the ambient context, available in both closure and data form. Both forms support All, Any, and Not, with True and False as the neutral elements of conjunction and disjunction.

Closure form (Req): direct and concise.

req := cove.All(
    cove.Req[Runtime](func(r Runtime) bool { return r.Budget > 0 }),
    cove.Req[Runtime](func(r Runtime) bool { return r.CanDispatch }),
)
ok := cove.Need(runtime, req)

Data form (ReqExpr): composable Boolean structure that avoids closure allocation during composition.

expr := cove.ExprAll(
    cove.ExprAtom(func(r Runtime) bool { return r.Budget > 0 }),
    cove.ExprAtom(func(r Runtime) bool { return r.CanDispatch }),
)
ok := cove.NeedExpr(runtime, expr)

Combinators: All/ExprAll (conjunction ∧), Any/ExprAny (disjunction ∨), Not/ExprNot (negation ¬), True/ExprTrue (⊤), False/ExprFalse (⊥).

Pullback and ExprPullback transport requirements contravariantly along a context projection. Given f: C → D, Pullback(req, f) maps Req[D] to Req[C]. ExprPullback preserves the Boolean structure and distributes over ExprNot, ExprAll, and ExprAny.

Choosing Req vs ReqExpr

Use Req for ad-hoc, one-off predicates. Use ReqExpr when composing many requirements, or when closure allocation at construction time matters.

Bridge helpers keep the two forms aligned: ReifyReq wraps a closure-form requirement as an ExprAtom, so ReifyReq(nil) is invalid and panics when evaluated; ReflectReq evaluates an Expr-form requirement through a closure.

Gated Values

Guard pairs a value with a requirement; IntoView yields a View only when the ambient context satisfies that requirement:

checked := cove.Guard(canDispatch, payload)
if view, ok := checked.IntoView(runtime); ok {
    _ = view.Extract()
}

GuardRule adds diagnostics via named rules and Report:

rule := cove.Require("budget", func(r Runtime) bool { return r.Budget > 0 })
guarded := cove.GuardRule(rule, payload)
if view, report := guarded.IntoView(runtime); report.OK() {
    _ = view.Extract()
}

CheckRules and CheckRulesExpr evaluate several rules in order, stopping at the first failure:

report := cove.CheckRules(runtime, budgetRule, permRule)
if !report.OK() {
    // report.Failed names the first rule that did not hold
}

The Expr-form diagnostic path has the same shape through CheckRulesExpr and GuardRuleExpr:

type Runtime struct{ Budget int }

runtime := Runtime{Budget: 1}
payload := "packet"
exprRule := cove.RequireExpr("budget", cove.ExprAtom(func(r Runtime) bool {
    return r.Budget > 0
}))
report := cove.CheckRulesExpr(runtime, exprRule)
if !report.OK() {
    return
}
guardedExpr := cove.GuardRuleExpr(exprRule, payload)
if view, report := guardedExpr.IntoView(runtime); report.OK() {
    _ = view.Extract()
}

Expr-form equivalents: GuardExpr, GuardRuleExpr, CheckedExpr, GuardedExpr. Map and pullback helpers: MapChecked, MapGuarded, PullbackChecked, PullbackGuarded (and their Expr variants).

View Operations

View[C, A] is a comonad over the category of Go types. The carrier is the product C × A; Extract (ε) projects the value; Duplicate (δ) embeds the observation as the focused value:

v := cove.Observe(ctx, value)
v.Ask()       // ambient context  (π₁)
v.Extract()   // value in focus   (ε = π₂)

Transformations: Map (functorial lift on A), MapContext (functorial lift on C), Replace (substitute the value), WithContext (substitute the context).

Duplicate and Extend satisfy the comonad laws:

// Counit law:  ε ∘ δ = id
cove.Duplicate(v).Extract() == v

// Extension identity:  extend(ε) = id
cove.Extend(v, func(w cove.View[C, A]) A { return w.Extract() }) == v

// Associativity:  extend(f) ∘ extend(g) = extend(f ∘ extend(g))

Extend is the contextual extension operator: given f: W(C, A) → B, it lifts f to W(C, A) → W(C, B) while preserving the ambient context. The induced command composition with g: W(C, B) → D is g ∘ Extend(f).

Ecosystem Position

Package Owns Categorical Aspect
kont Effect operations, handlers, suspension and resumption Algebra / Free monad / Fold
cove Ambient context across suspension boundaries Coalgebra / Comonad / Unfold
takt Proactor dispatch, outcome classification, event loop Comodel (handler dual)
uring Kernel I/O: SQE/CQE, ring management, buffer rings
iox Outcome algebra and error semantics

Formal Structure

View[C, A] is an environment comonad (Uustalu & Vene 2008) with carrier C × A, counit ε = π₂ (Extract), and comultiplication δ(c, a) = (c, (c, a)) (Duplicate). Extend implements contextual extension (coKleisli extension in the categorical literature).

Req[C] and ReqExpr[C] are objects in the Boolean algebra of predicates over C. Pullback implements the contravariant functor f* induced by a morphism f: C → D, mapping predicates on D to predicates on C. ExprPullback preserves the Boolean algebra structure: f*(p ∧ q) = f*(p) ∧ f*(q), f*(¬p) = ¬f*(p).

kont models algebraic effects (free monad, handlers, fold); cove models coeffects (comonad, requirements, unfold). The two are categorical duals at the suspension boundary: kont describes what the computation does to the world, whereas cove states what the computation needs from the world.

Read through the lens of modal effects, the carrier shape can be read as naming what happens to ambient context: kont ( C → D) replaces it, cove (W(C, A) → B) handles it relatively, and pure pass-through preserves it. Effect structure rides on the carrier, not on a function colour, which keeps cove policy-free.

ReqExpr defunctionalizes the Boolean algebra into a tagged union, namely the initial algebra of the Boolean signature functor, so that the structure of a requirement is inspectable data rather than an opaque closure (Reynolds 1972).

Practical Recipes

A complete contextual computation typically proceeds in three stages: declare requirements, gate values against them, then observe the result under a concrete context.

// 1. Declare a requirement on the ambient context.
type Caps struct{ CanSubmit, HasToken bool }
req := cove.All(
func (c Caps) bool { return c.CanSubmit },
func (c Caps) bool { return c.HasToken },
)

// 2. Gate a value on that requirement. This produces a Checked[Caps, T].
checked := cove.Guard(req, payload)

// 3. Reify into an Expr to step under different ambient contexts.
expr := cove.ReifyReq(req)
ok := cove.NeedExpr(Caps{CanSubmit: true, HasToken: true}, expr)
_ = checked
_ = ok

Pullback lets a caller adapt a requirement defined over one context so that it works over another (Pullback(req, f) for f: D → C); MapChecked and MapGuarded transport gated values through value-level transformations without re-checking the predicate. The combination All + Pullback + Guard is how downstream packages build typed capability checks without coupling to a single context type.

References

  • John C. Reynolds. 1972. Definitional Interpreters for Higher-Order Programming Languages. In Proc. ACM Annual Conference (ACM '72). 717–740. https://doi.org/10.1145/800194.805852
  • Tarmo Uustalu and Varmo Vene. 2008. Comonadic Notions of Computation. Electronic Notes in Theoretical Computer Science 203, 5 (June 2008), 263–284. https://doi.org/10.1016/j.entcs.2008.05.029
  • Tomas Petricek, Dominic Orchard, and Alan Mycroft. 2014. Coeffects: A Calculus of Context-Dependent Computation. In Proc. 19th ACM SIGPLAN International Conference on Functional Programming (ICFP '14). 123–135. https://tomasp.net/academic/papers/structural/coeffects-icfp.pdf
  • Marco Gaboardi, Shin-ya Katsumata, Dominic Orchard, Flavien Breuvart, and Tarmo Uustalu. 2016. Combining Effects and Coeffects via Grading. In Proc. 21st ACM SIGPLAN International Conference on Functional Programming (ICFP '16). 476–489. https://doi.org/10.1145/2951913.2951939
  • Jonathan Immanuel Brachthäuser, Philipp Schuster, and Klaus Ostermann. 2020. Effects as Capabilities: Effect Handlers and Lightweight Effect Polymorphism. Proc. ACM on Programming Languages 4, OOPSLA (Nov. 2020), Article 126, 30 pages. https://se.cs.uni-tuebingen.de/publications/brachthaeuser20effekt.pdf
  • Daniel Gratzer, G. A. Kavvos, Andreas Nuyts, and Lars Birkedal. 2021. Multimodal Dependent Type Theory. Logical Methods in Computer Science 17, 3 (2021), Paper 11, 67 pages. https://doi.org/10.46298/lmcs-17(3:11)2021
  • Wenhao Tang, Leo White, Stephen Dolan, Daniel Hillerström, Sam Lindley, and Anton Lorenzen. 2025. Modal Effect Types. Proc. ACM Program. Lang. 9, OOPSLA1 (Apr. 2025), Article 120, 1130–1157. https://arxiv.org/abs/2407.11816
  • Wenhao Tang and Sam Lindley. 2026. Rows and Capabilities as Modal Effects. Proc. ACM Program. Lang. 10, POPL (Jan. 2026), 923–950. https://arxiv.org/abs/2507.10301

Platform Support

cove is a pure Go package in this module. It has no platform-specific files or build tags; the module requirement is Go 1.26+.

License

MIT License. See LICENSE for details.

©2026 Hayabusa Cloud Co., Ltd.

Documentation

Overview

Package cove carries explicit ambient context across kont suspension boundaries.

When a runtime advances a kont computation one suspension at a time, each suspended operation may depend on state that lives outside the operation itself, such as dispatch budget, ring capabilities, protocol phase, or buffer-group validity. cove pairs that context with values and suspensions so it stays explicit across asynchronous boundaries instead of travelling through hidden globals or ad-hoc side maps.

Read through the lens of modal effects, the carrier shape can be read as naming what happens to ambient context: kont (C → D) replaces it, cove (W(C, A) → B) handles it relatively, and pure pass-through preserves it. Effect structure rides on the carrier, not on a function colour, which keeps cove policy-free.

Responsibilities stay split by layer:

The package is policy-free: it carries and checks context but never schedules, retries, or dispatches. Kernel mechanics belong to uring, and semantic outcome branching belongs to iox, including code.hybscloud.com/iox.Classify. The join point with takt is structural: a contextual carrier exposes the current suspended operation and accepts the matching resumption without transferring ownership of the context to the runner.

Carriers:

  • [View[C, A]], a focused value paired with ambient context
  • [Cmd[C, A, B]], a contextual command over View
  • [SuspensionView[C, A]], a kont.Suspension paired with ambient context
  • [Req[C]] / [ReqExpr[C]], context predicates in closure and data forms
  • [Rule[C]] / [RuleExpr[C]] with Report, named predicates for diagnostics
  • [Checked[C, A]] / [CheckedExpr[C, A]], requirement-gated values
  • [Guarded[C, A]] / [GuardedExpr[C, A]], rule-gated values

Commands:

  • ExtractCmd returns the focused value as the identity contextual command
  • LiftCmd lifts a focus-only transform into a contextual command
  • Compose composes contextual commands through Extend
  • Run applies a command to a concrete View

Contextual suspension boundary:

Bridge helpers:

Laws:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractCmd added in v0.1.0

func ExtractCmd[C Ambient, A Focus](v View[C, A]) A

ExtractCmd returns the focused value and serves as the identity command for View.

func Need

func Need[C Ambient](ctx C, req Req[C]) bool

Need reports whether ctx satisfies req. A nil requirement is treated as true.

func NeedExpr

func NeedExpr[C Ambient](ctx C, req ReqExpr[C]) bool

NeedExpr reports whether ctx satisfies req.

func Reflect

func Reflect[A Focus](m kont.Expr[A]) kont.Cont[Resumed, A]

Reflect converts a kont.Expr computation to kont.Cont. Prefer StepWith or StepExprWith when the caller needs the contextual suspension boundary.

func Reify

func Reify[A Focus](m kont.Cont[Resumed, A]) kont.Expr[A]

Reify converts a kont.Cont computation to kont.Expr. Prefer StepWith or StepExprWith when the caller needs the contextual suspension boundary.

func Run added in v0.1.0

func Run[C Ambient, A, B Focus](v View[C, A], cmd Cmd[C, A, B]) B

Run applies cmd to v.

func Step

func Step[A Focus](m kont.Cont[Resumed, A]) (A, *kont.Suspension[A])

Step re-exports kont.Step. Prefer StepWith when the suspension should remain paired with explicit context.

func StepExpr

func StepExpr[A Focus](m kont.Expr[A]) (A, *kont.Suspension[A])

StepExpr re-exports kont.StepExpr. Prefer StepExprWith when the suspension should remain paired with explicit context.

Types

type Ambient

type Ambient interface{}

Ambient constrains ambient context type parameters.

type Checked

type Checked[C Ambient, A Focus] struct {
	Req   Req[C]
	Value A
}

Checked pairs a value with a requirement.

func Guard

func Guard[C Ambient, A Focus](req Req[C], value A) Checked[C, A]

Guard constructs a checked value.

func MapChecked

func MapChecked[C Ambient, A, B Focus](c Checked[C, A], f func(A) B) Checked[C, B]

MapChecked maps the value and preserves the requirement.

func PullbackChecked

func PullbackChecked[C, D Ambient, A Focus](checked Checked[C, A], f func(D) C) Checked[D, A]

PullbackChecked transports c along a context projection.

func (Checked[C, A]) Check

func (c Checked[C, A]) Check(ctx C) bool

Check reports whether ctx satisfies c's requirement.

func (Checked[C, A]) IntoView

func (c Checked[C, A]) IntoView(ctx C) (View[C, A], bool)

IntoView returns a view when c's requirement holds.

func (Checked[C, A]) MustView

func (c Checked[C, A]) MustView(ctx C) View[C, A]

MustView returns a view and panics if c's requirement does not hold.

type CheckedExpr

type CheckedExpr[C Ambient, A Focus] struct {
	Req   ReqExpr[C]
	Value A
}

CheckedExpr pairs a value with a requirement expression.

func GuardExpr

func GuardExpr[C Ambient, A Focus](req ReqExpr[C], value A) CheckedExpr[C, A]

GuardExpr constructs a checked value from a requirement expression.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type runtime struct{ Budget int }
	checked := cove.GuardExpr(
		cove.ExprAtom(func(r runtime) bool { return r.Budget > 0 }),
		"payload",
	)
	view, ok := checked.IntoView(runtime{Budget: 2})
	fmt.Println(ok, view.Extract())
	_, ok = checked.IntoView(runtime{Budget: 0})
	fmt.Println(ok)
}
Output:
true payload
false

func MapCheckedExpr

func MapCheckedExpr[C Ambient, A, B Focus](c CheckedExpr[C, A], f func(A) B) CheckedExpr[C, B]

MapCheckedExpr maps the value and preserves the requirement.

func PullbackCheckedExpr

func PullbackCheckedExpr[C, D Ambient, A Focus](checked CheckedExpr[C, A], f func(D) C) CheckedExpr[D, A]

PullbackCheckedExpr transports c along a context projection.

func (CheckedExpr[C, A]) Check

func (c CheckedExpr[C, A]) Check(ctx C) bool

Check reports whether ctx satisfies c's requirement.

func (CheckedExpr[C, A]) IntoView

func (c CheckedExpr[C, A]) IntoView(ctx C) (View[C, A], bool)

IntoView returns a view when c's requirement holds.

func (CheckedExpr[C, A]) MustView

func (c CheckedExpr[C, A]) MustView(ctx C) View[C, A]

MustView returns a view and panics if c's requirement does not hold.

type Cmd added in v0.1.0

type Cmd[C Ambient, A, B Focus] func(View[C, A]) B

Cmd is a contextual command over View.

func Compose added in v0.1.0

func Compose[C Ambient, A, B, D Focus](g Cmd[C, B, D], f Cmd[C, A, B]) Cmd[C, A, D]

Compose composes contextual commands through Extend.

func LiftCmd added in v0.1.0

func LiftCmd[C Ambient, A, B Focus](f func(A) B) Cmd[C, A, B]

LiftCmd lifts a focus-only function into a contextual command.

type Focus

type Focus interface{}

Focus constrains type parameters that represent focused values.

type Guarded

type Guarded[C Ambient, A Focus] struct {
	Rule  Rule[C]
	Value A
}

Guarded pairs a value with a named rule.

func GuardRule

func GuardRule[C Ambient, A Focus](rule Rule[C], value A) Guarded[C, A]

GuardRule constructs a guarded value.

func MapGuarded

func MapGuarded[C Ambient, A, B Focus](g Guarded[C, A], f func(A) B) Guarded[C, B]

MapGuarded maps the value and preserves the rule.

func PullbackGuarded

func PullbackGuarded[C, D Ambient, A Focus](guarded Guarded[C, A], f func(D) C) Guarded[D, A]

PullbackGuarded transports g along a context projection.

func (Guarded[C, A]) Check

func (g Guarded[C, A]) Check(ctx C) Report

Check checks the guarded rule against ctx.

func (Guarded[C, A]) IntoView

func (g Guarded[C, A]) IntoView(ctx C) (View[C, A], Report)

IntoView returns a view together with the rule report.

type GuardedExpr

type GuardedExpr[C Ambient, A Focus] struct {
	Rule  RuleExpr[C]
	Value A
}

GuardedExpr pairs a value with a named requirement expression.

func GuardRuleExpr

func GuardRuleExpr[C Ambient, A Focus](rule RuleExpr[C], value A) GuardedExpr[C, A]

GuardRuleExpr constructs a guarded value from a rule expression.

func MapGuardedExpr

func MapGuardedExpr[C Ambient, A, B Focus](g GuardedExpr[C, A], f func(A) B) GuardedExpr[C, B]

MapGuardedExpr maps the value and preserves the rule.

func PullbackGuardedExpr

func PullbackGuardedExpr[C, D Ambient, A Focus](guarded GuardedExpr[C, A], f func(D) C) GuardedExpr[D, A]

PullbackGuardedExpr transports g along a context projection.

func (GuardedExpr[C, A]) Check

func (g GuardedExpr[C, A]) Check(ctx C) Report

Check checks the guarded rule against ctx.

func (GuardedExpr[C, A]) IntoView

func (g GuardedExpr[C, A]) IntoView(ctx C) (View[C, A], Report)

IntoView returns a view together with the rule report.

type Operation

type Operation = kont.Operation

Operation is the payload type carried by a kont suspension boundary.

type Report

type Report struct {
	Failed  RuleError // zero value means success
	Checked int       // number of rules examined before success or first failure
}

Report records the result of checking one or more named rules.

func CheckRule

func CheckRule[C Ambient](ctx C, rule Rule[C]) Report

CheckRule checks a single rule.

func CheckRuleExpr

func CheckRuleExpr[C Ambient](ctx C, rule RuleExpr[C]) Report

CheckRuleExpr checks a single rule expression.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type runtime struct{ Budget int }
	rule := cove.RequireExpr("budget", cove.ExprAtom(func(r runtime) bool {
		return r.Budget > 0
	}))
	report := cove.CheckRuleExpr(runtime{Budget: 5}, rule)
	fmt.Println(report.OK())
	report = cove.CheckRuleExpr(runtime{Budget: 0}, rule)
	fmt.Println(report.OK(), report.Failed)
}
Output:
true
false budget

func CheckRules

func CheckRules[C Ambient](ctx C, rules ...Rule[C]) Report

CheckRules checks rules from left to right and stops at the first failure.

func CheckRulesExpr

func CheckRulesExpr[C Ambient](ctx C, rules ...RuleExpr[C]) Report

CheckRulesExpr checks rule expressions from left to right and stops at the first failure.

func (Report) Err added in v0.1.0

func (r Report) Err() error

Err returns the first failed rule as an error, or nil on success.

func (Report) FailedRule added in v0.1.0

func (r Report) FailedRule() string

FailedRule reports the first failed rule label, or "" on success.

For direct Rule literals with an empty name, the label falls back to "cove: unnamed rule".

func (Report) OK

func (r Report) OK() bool

OK reports whether every checked rule passed.

type Req

type Req[C Ambient] func(C) bool

Req is a requirement over ambient context C.

func All

func All[C Ambient](reqs ...Req[C]) Req[C]

All returns the conjunction of reqs.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type caps struct {
		CanSubmit bool
		HasToken  bool
	}
	req := cove.All(
		func(c caps) bool { return c.CanSubmit },
		func(c caps) bool { return c.HasToken },
	)
	fmt.Println(cove.Need(caps{CanSubmit: true, HasToken: true}, req))
}
Output:
true

func Any

func Any[C Ambient](reqs ...Req[C]) Req[C]

Any returns the disjunction of reqs.

func False

func False[C Ambient]() Req[C]

False returns a requirement that never holds.

func Not

func Not[C Ambient](req Req[C]) Req[C]

Not returns the negation of req.

func Pullback

func Pullback[C, D Ambient](req Req[D], f func(C) D) Req[C]

Pullback transports req along a context projection.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type runtime struct{ Budget int }
	req := cove.Pullback(func(budget int) bool { return budget > 0 }, func(rt runtime) int {
		return rt.Budget
	})
	fmt.Println(cove.Need(runtime{Budget: 2}, req))
}
Output:
true

func ReflectReq

func ReflectReq[C Ambient](expr ReqExpr[C]) Req[C]

ReflectReq returns a closure-form requirement that delegates to NeedExpr.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type runtime struct {
		Budget      int
		CanDispatch bool
	}
	expr := cove.ExprAll(
		cove.ExprAtom(func(r runtime) bool { return r.Budget > 0 }),
		cove.ExprAtom(func(r runtime) bool { return r.CanDispatch }),
	)
	req := cove.ReflectReq(expr)
	ctx := runtime{Budget: 2, CanDispatch: true}
	fmt.Println(cove.NeedExpr(ctx, expr))
	fmt.Println(cove.Need(ctx, req))
}
Output:
true
true

func True

func True[C Ambient]() Req[C]

True returns a requirement that always holds.

type ReqExpr

type ReqExpr[C Ambient] struct {
	// contains filtered or unexported fields
}

ReqExpr stores a requirement as data instead of a closure. The zero value is ExprTrue.

func ExprAll

func ExprAll[C Ambient](reqs ...ReqExpr[C]) ReqExpr[C]

ExprAll returns the conjunction of reqs.

func ExprAny

func ExprAny[C Ambient](reqs ...ReqExpr[C]) ReqExpr[C]

ExprAny returns the disjunction of reqs.

func ExprAtom

func ExprAtom[C Ambient](fn func(C) bool) ReqExpr[C]

ExprAtom wraps a leaf predicate as a requirement expression.

func ExprFalse

func ExprFalse[C Ambient]() ReqExpr[C]

ExprFalse returns a requirement that never holds.

func ExprNot

func ExprNot[C Ambient](inner ReqExpr[C]) ReqExpr[C]

ExprNot returns the negation of inner.

func ExprPullback

func ExprPullback[C, D Ambient](req ReqExpr[D], f func(C) D) ReqExpr[C]

ExprPullback transports req along a context projection and preserves its explicit Boolean structure.

func ExprTrue

func ExprTrue[C Ambient]() ReqExpr[C]

ExprTrue returns a requirement that always holds.

func ReifyReq

func ReifyReq[C Ambient](req Req[C]) ReqExpr[C]

ReifyReq wraps a Req as an ExprAtom.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	req := cove.Req[int](func(v int) bool { return v > 0 })
	expr := cove.ReifyReq(req)
	fmt.Println(cove.NeedExpr(1, expr))
	fmt.Println(cove.NeedExpr(-1, expr))
}
Output:
true
false

type Resumed

type Resumed = kont.Resumed

Resumed is the value type used to resume a kont suspension boundary.

type Rule

type Rule[C Ambient] struct {
	Name  string
	Check Req[C]
}

Rule names a requirement for diagnostics.

func PullbackRule

func PullbackRule[C, D Ambient](rule Rule[C], f func(D) C) Rule[D]

PullbackRule transports r along a context projection.

func Require

func Require[C Ambient](name string, check Req[C]) Rule[C]

Require constructs a named rule.

func (Rule[C]) Match

func (r Rule[C]) Match(ctx C) bool

Match reports whether ctx satisfies r.

func (Rule[C]) Req

func (r Rule[C]) Req() Req[C]

Req returns the underlying requirement.

type RuleError

type RuleError string

RuleError names the first failed rule in a report.

func (RuleError) Error added in v0.1.0

func (e RuleError) Error() string

Error returns the failed rule label.

For direct Rule literals with an empty name, the label falls back to "cove: unnamed rule".

type RuleExpr

type RuleExpr[C Ambient] struct {
	Name  string
	Check ReqExpr[C]
}

RuleExpr names a requirement expression for diagnostics.

func PullbackRuleExpr

func PullbackRuleExpr[C, D Ambient](rule RuleExpr[C], f func(D) C) RuleExpr[D]

PullbackRuleExpr transports r along a context projection.

func RequireExpr

func RequireExpr[C Ambient](name string, check ReqExpr[C]) RuleExpr[C]

RequireExpr constructs a named requirement expression for diagnostics.

func (RuleExpr[C]) Match

func (r RuleExpr[C]) Match(ctx C) bool

Match reports whether ctx satisfies the rule.

func (RuleExpr[C]) Req

func (r RuleExpr[C]) Req() ReqExpr[C]

Req returns the underlying requirement expression.

type SuspensionView

type SuspensionView[C Ambient, A Focus] struct {
	Ctx        C
	Suspension *kont.Suspension[A]
}

SuspensionView pairs a kont.Suspension with ambient context. Its Op and Resume methods keep the carrier structurally joinable with `takt` without transferring ownership of the carried context to the runner. A nil Suspension means the computation has completed; Op, Resume, ResumeWith, and Discard panic after completion.

func CheckSuspension

func CheckSuspension[C Ambient, A Focus](ctx C, susp *kont.Suspension[A], req Req[C]) (SuspensionView[C, A], bool)

CheckSuspension returns a suspension view when req holds.

func CheckSuspensionExpr

func CheckSuspensionExpr[C Ambient, A Focus](ctx C, susp *kont.Suspension[A], req ReqExpr[C]) (SuspensionView[C, A], bool)

CheckSuspensionExpr returns a suspension view when req holds in expression form.

func MapContextSuspension added in v0.1.0

func MapContextSuspension[C, D Ambient, A Focus](v SuspensionView[C, A], f func(C) D) SuspensionView[D, A]

MapContextSuspension maps the ambient context and preserves the observed suspension frontier.

func ObserveSuspension

func ObserveSuspension[C Ambient, A Focus](ctx C, susp *kont.Suspension[A]) SuspensionView[C, A]

ObserveSuspension returns a suspension view for ctx and susp.

func StepExprWith

func StepExprWith[C Ambient, A Focus](ctx C, m kont.Expr[A]) (A, SuspensionView[C, A])

StepExprWith runs an Expr computation and pairs its first suspension with ctx. It is the primary contextual stepping entry point for callers already in Expr form.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
	"code.hybscloud.com/kont"
)

func main() {
	type runtime struct{ Budget int }
	type ping struct{ kont.Phantom[int] }

	expr := kont.ExprBind(kont.ExprPerform(ping{}), func(v int) kont.Expr[int] {
		return kont.ExprReturn(v + 1)
	})

	_, step := cove.StepExprWith(runtime{Budget: 2}, expr)
	fmt.Println(step.Suspension != nil)
	fmt.Println(step.Ask().Budget)
	_, isPing := step.Op().(ping)
	fmt.Println(isPing)
	result, sv := step.Resume(41)
	fmt.Println(result, sv.Suspension != nil)
}
Output:
true
2
true
42 false

func StepWith

func StepWith[C Ambient, A Focus](ctx C, m kont.Cont[Resumed, A]) (A, SuspensionView[C, A])

StepWith runs a Cont computation and pairs its first suspension with ctx. It is the primary contextual stepping entry point.

func WithContextSuspension added in v0.1.0

func WithContextSuspension[C Ambient, A Focus](v SuspensionView[C, A], ctx C) SuspensionView[C, A]

WithContextSuspension replaces the ambient context and preserves the observed suspension frontier.

func (SuspensionView[C, A]) Ask

func (v SuspensionView[C, A]) Ask() C

Ask returns the ambient context.

func (SuspensionView[C, A]) Discard

func (v SuspensionView[C, A]) Discard()

Discard consumes the suspension without resuming it. It panics after completion.

func (SuspensionView[C, A]) Extract

func (v SuspensionView[C, A]) Extract() *kont.Suspension[A]

Extract returns the underlying suspension.

func (SuspensionView[C, A]) Op

func (v SuspensionView[C, A]) Op() Operation

Op returns the suspended operation. It panics after completion.

func (SuspensionView[C, A]) Resume

func (v SuspensionView[C, A]) Resume(value Resumed) (A, SuspensionView[C, A])

Resume advances the suspension and keeps the current context. It panics after completion.

func (SuspensionView[C, A]) ResumeWith

func (v SuspensionView[C, A]) ResumeWith(value Resumed, f func(C) C) (A, SuspensionView[C, A])

ResumeWith advances the suspension and optionally maps the context for the next step. It panics after completion. A nil mapper keeps the current context, so ResumeWith strictly generalizes [Resume].

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
	"code.hybscloud.com/kont"
)

func main() {
	type runtime struct {
		Budget int
		kont.Phantom[int]
	}
	type ping struct{ kont.Phantom[int] }

	expr := kont.ExprBind(kont.ExprPerform(ping{}), func(v int) kont.Expr[int] {
		return kont.ExprReturn(v + 1)
	})

	_, step := cove.StepExprWith(runtime{Budget: 10}, expr)
	fmt.Println(step.Ask().Budget)
	result, sv := step.ResumeWith(41, func(r runtime) runtime {
		r.Budget--
		return r
	})
	fmt.Println(result, sv.Suspension != nil)
}
Output:
10
42 false

type View

type View[C Ambient, A Focus] struct {
	Ctx   C
	Value A
}

View represents a focused value under ambient context.

func Duplicate

func Duplicate[C Ambient, A Focus](v View[C, A]) View[C, View[C, A]]

Duplicate returns the whole view as the new focused value.

func Extend

func Extend[C Ambient, A, B Focus](v View[C, A], f func(View[C, A]) B) View[C, B]

Extend applies f to the whole view and preserves the ambient context. Together with [Extract] and Duplicate, it defines the core view operations.

Example
package main

import (
	"fmt"

	"code.hybscloud.com/cove"
)

func main() {
	type ctx struct{ Budget int }
	v := cove.Observe(ctx{Budget: 4}, 10)
	next := cove.Extend(v, func(v cove.View[ctx, int]) int {
		return v.Value + v.Ctx.Budget
	})
	fmt.Println(next.Extract())
}
Output:
14

func Map

func Map[C Ambient, A, B Focus](v View[C, A], f func(A) B) View[C, B]

Map maps the focused value and preserves the ambient context.

func MapContext

func MapContext[C, D Ambient, A Focus](v View[C, A], f func(C) D) View[D, A]

MapContext maps the ambient context and preserves the focused value.

func Observe

func Observe[C Ambient, A Focus](ctx C, value A) View[C, A]

Observe returns a view for ctx and value.

func Replace

func Replace[C Ambient, A, B Focus](v View[C, A], value B) View[C, B]

Replace substitutes the focused value and preserves the ambient context.

func WithContext

func WithContext[C Ambient, A Focus](v View[C, A], ctx C) View[C, A]

WithContext substitutes the ambient context and preserves the focused value.

func (View[C, A]) Ask

func (v View[C, A]) Ask() C

Ask returns the ambient context.

func (View[C, A]) Extract

func (v View[C, A]) Extract() A

Extract returns the focused value.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL