Expert skill for designing and implementing algebraic effect systems including effect annotation, inference, handlers, polymorphism, and row-based effect typing.
Designs and implements algebraic effect systems for tracking and handling computational effects in programming languages.
npx claudepluginhub a5c-ai/babysitterThis skill is limited to using the following tools:
README.mdDesign and implement algebraic effect systems for tracking and handling computational effects in programming languages.
Invoke this skill when you need to:
| Parameter | Type | Required | Description |
|---|---|---|---|
| effectModel | string | Yes | Model (algebraic, monadic, capability) |
| inferenceStrategy | string | Yes | Strategy (annotated, inferred, mixed) |
| features | array | No | Features to implement |
| builtinEffects | array | No | Built-in effects to include |
{
"effectModel": "algebraic", // Koka/Eff style
"effectModel": "monadic", // Haskell IO style
"effectModel": "capability" // Capability-based
}
{
"features": [
"effect-inference",
"effect-handlers",
"effect-polymorphism",
"effect-rows",
"effect-subtyping",
"effect-abstraction",
"resumption-control",
"multi-shot-continuations"
]
}
effect-system/
├── syntax/
│ ├── effect-annotation.grammar # Effect annotation syntax
│ ├── effect-handler.grammar # Handler syntax
│ └── effect-operation.grammar # Operation syntax
├── typing/
│ ├── effect-types.ts # Effect type definitions
│ ├── effect-inference.ts # Effect inference
│ ├── effect-checking.ts # Effect checking
│ └── effect-rows.ts # Row polymorphism
├── handlers/
│ ├── handler-impl.ts # Handler implementation
│ ├── continuation.ts # Continuation management
│ └── resumption.ts # Resumption handling
├── runtime/
│ ├── effect-runtime.ts # Runtime effect support
│ └── builtin-effects.ts # Built-in effects
└── tests/
├── inference.test.ts
├── handlers.test.ts
└── polymorphism.test.ts
// Effect declaration
effect State<S> {
get(): S
put(s: S): ()
}
effect Exception<E> {
raise(e: E): Nothing
}
// Effect types
type EffectType = {
operations: Map<string, OperationType>;
}
interface OperationType {
name: string;
params: Type[];
result: Type;
}
// Function types with effects
interface FunctionType {
params: Type[];
result: Type;
effects: EffectRow;
}
// Effect rows (for polymorphism)
type EffectRow =
| { type: 'empty' }
| { type: 'single'; effect: EffectType }
| { type: 'union'; effects: EffectType[] }
| { type: 'variable'; name: string } // Effect polymorphism
| { type: 'extend'; base: EffectRow; effect: EffectType };
// Handler syntax
handle expr with {
return(x) -> returnClause(x),
get() -> getClause(resume),
put(s) -> putClause(s, resume)
}
// Handler representation
interface Handler {
effect: EffectType;
returnClause: (value: any) => any;
operationClauses: Map<string, OperationClause>;
}
interface OperationClause {
operation: string;
params: string[];
resumeName: string;
body: Expr;
}
// Handler typing
// handle[E] : (() -E> A) -> ((A -> B) & Handler[E]) -> B
function typeHandler(
expr: Expr,
handler: Handler,
env: TypeEnv
): { resultType: Type; remainingEffects: EffectRow } {
const exprType = inferType(expr, env);
// Check that handler handles the effect
checkHandlerCovers(handler, exprType.effects);
// Result type comes from handler clauses
const resultType = inferHandlerResult(handler, exprType.result, env);
// Remove handled effect from row
const remainingEffects = removeEffect(exprType.effects, handler.effect);
return { resultType, remainingEffects };
}
// Effect inference algorithm
function inferEffects(expr: Expr, env: TypeEnv): InferResult {
switch (expr.type) {
case 'var':
return { type: lookupType(env, expr.name), effects: emptyRow() };
case 'lambda':
const bodyResult = inferEffects(expr.body, extendEnv(env, expr.param, expr.paramType));
return {
type: { type: 'function', param: expr.paramType, result: bodyResult.type, effects: bodyResult.effects },
effects: emptyRow() // Lambda itself is pure
};
case 'app':
const fnResult = inferEffects(expr.fn, env);
const argResult = inferEffects(expr.arg, env);
const fnType = fnResult.type as FunctionType;
return {
type: fnType.result,
effects: unionRows(fnResult.effects, argResult.effects, fnType.effects)
};
case 'perform':
const opType = lookupOperation(env, expr.effect, expr.operation);
const argEffects = expr.args.map(a => inferEffects(a, env).effects);
return {
type: opType.result,
effects: unionRows(singleRow(expr.effect), ...argEffects)
};
case 'handle':
const exprResult = inferEffects(expr.body, env);
const handlerResult = checkHandler(expr.handler, exprResult, env);
return handlerResult;
// ... other cases
}
}
// Effect-polymorphic function
// map : forall E. (a -E> b) -> List a -E> List b
interface EffectPolymorphicType {
effectVars: string[];
typeVars: string[];
type: Type;
}
// Row polymorphism for effects
// foo : () -<State, E>-> Int (E is a row variable)
type RowVariable = { type: 'rowVar'; name: string };
function unifyRows(row1: EffectRow, row2: EffectRow): Substitution {
// Row unification algorithm
if (row1.type === 'variable') {
return { [row1.name]: row2 };
}
if (row2.type === 'variable') {
return { [row2.name]: row1 };
}
if (row1.type === 'empty' && row2.type === 'empty') {
return {};
}
// Handle union and extend cases...
}
// Delimited continuations for effect handlers
interface Continuation<A, B> {
resume(value: A): B;
}
// Multi-shot continuations (can resume multiple times)
interface MultiShotContinuation<A, B> extends Continuation<A, B> {
clone(): MultiShotContinuation<A, B>;
}
// One-shot continuations (can only resume once)
interface OneShotContinuation<A, B> extends Continuation<A, B> {
readonly consumed: boolean;
}
// Runtime continuation capture
class ContinuationCapture {
capture<A, B>(
prompt: Prompt,
body: (k: Continuation<A, B>) => B
): B {
// Capture the current continuation up to prompt
const k = captureDelimited(prompt);
return body(k);
}
}
// Common built-in effects
const builtinEffects = {
IO: {
operations: {
print: { params: [StringType], result: UnitType },
readLine: { params: [], result: StringType },
readFile: { params: [StringType], result: StringType },
writeFile: { params: [StringType, StringType], result: UnitType }
}
},
State: {
typeParams: ['S'],
operations: {
get: { params: [], result: TypeVar('S') },
put: { params: [TypeVar('S')], result: UnitType }
}
},
Exception: {
typeParams: ['E'],
operations: {
raise: { params: [TypeVar('E')], result: NothingType }
}
},
Async: {
operations: {
await: { params: [PromiseType(TypeVar('A'))], result: TypeVar('A') },
spawn: { params: [FunctionType([], TypeVar('A'), AsyncEffect)], result: TaskType(TypeVar('A')) }
}
},
NonDet: {
operations: {
choice: { params: [], result: BoolType },
fail: { params: [], result: NothingType }
}
}
};
// Pure functions can be optimized more aggressively
function canOptimize(fn: FunctionType): OptimizationLevel {
if (isEmptyRow(fn.effects)) {
return 'pure'; // Full optimization: CSE, memoization, parallelization
}
if (onlyReads(fn.effects)) {
return 'read-only'; // Can reorder, CSE
}
if (isLocalState(fn.effects)) {
return 'local-state'; // Can inline, but not reorder
}
return 'effectful'; // Limited optimization
}
// Effect-based dead code elimination
function eliminateDeadCode(expr: Expr): Expr {
const effects = inferEffects(expr);
if (isEmptyRow(effects) && !isUsed(expr)) {
return unit; // Pure unused expression can be eliminated
}
return expr;
}
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.