name: effect-systems description: 设计和实现代数效应系统的专家技能,包括效应标注、推断、处理器、多态性和基于行的效应类型系统。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep
效应系统技能
为编程语言设计和实现代数效应系统,以追踪和处理计算效应。
能力
- 设计效应标注语法
- 实现效应推断算法
- 实现效应检查和追踪
- 设计效应处理器(代数效应)
- 处理效应多态性
- 实现效应行和可扩展性
- 设计效应子类型
- 生成基于效应的优化
使用场景
在以下情况时调用此技能:
- 为语言添加效应系统
- 实现代数效应和处理器
- 在类型中追踪计算效应
- 设计效应多态性
输入参数
| 参数 | 类型 | 是否必需 | 描述 |
|---|---|---|---|
| effectModel | string | 是 | 模型(代数、单子、能力) |
| inferenceStrategy | string | 是 | 策略(标注、推断、混合) |
| features | array | 否 | 要实现的特性 |
| builtinEffects | array | 否 | 要包含的内置效应 |
效应模型选项
{
"effectModel": "algebraic", // Koka/Eff 风格
"effectModel": "monadic", // Haskell IO 风格
"effectModel": "capability" // 基于能力
}
特性选项
{
"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-handler.grammar # 处理器语法
│ └── effect-operation.grammar # 操作语法
├── typing/
│ ├── effect-types.ts # 效应类型定义
│ ├── effect-inference.ts # 效应推断
│ ├── effect-checking.ts # 效应检查
│ └── effect-rows.ts # 行多态性
├── handlers/
│ ├── handler-impl.ts # 处理器实现
│ ├── continuation.ts # 延续管理
│ └── resumption.ts # 恢复处理
├── runtime/
│ ├── effect-runtime.ts # 运行时效应支持
│ └── builtin-effects.ts # 内置效应
└── tests/
├── inference.test.ts
├── handlers.test.ts
└── polymorphism.test.ts
效应系统类型
代数效应(Koka风格)
// 效应声明
effect State<S> {
get(): S
put(s: S): ()
}
effect Exception<E> {
raise(e: E): Nothing
}
// 效应类型
type EffectType = {
operations: Map<string, OperationType>;
}
interface OperationType {
name: string;
params: Type[];
result: Type;
}
// 带效应的函数类型
interface FunctionType {
params: Type[];
result: Type;
effects: EffectRow;
}
// 效应行(用于多态性)
type EffectRow =
| { type: 'empty' }
| { type: 'single'; effect: EffectType }
| { type: 'union'; effects: EffectType[] }
| { type: 'variable'; name: string } // 效应多态性
| { type: 'extend'; base: EffectRow; effect: EffectType };
效应处理器
// 处理器语法
handle expr with {
return(x) -> returnClause(x),
get() -> getClause(resume),
put(s) -> putClause(s, resume)
}
// 处理器表示
interface Handler {
effect: EffectType;
returnClause: (value: any) => any;
operationClauses: Map<string, OperationClause>;
}
interface OperationClause {
operation: string;
params: string[];
resumeName: string;
body: Expr;
}
// 处理器类型检查
// 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);
// 检查处理器是否覆盖该效应
checkHandlerCovers(handler, exprType.effects);
// 结果类型来自处理器子句
const resultType = inferHandlerResult(handler, exprType.result, env);
// 从行中移除已处理的效应
const remainingEffects = removeEffect(exprType.effects, handler.effect);
return { resultType, remainingEffects };
}
效应推断
// 效应推断算法
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 本身是纯的
};
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;
// ... 其他情况
}
}
效应多态性
// 效应多态函数
// map : forall E. (a -E> b) -> List a -E> List b
interface EffectPolymorphicType {
effectVars: string[];
typeVars: string[];
type: Type;
}
// 效应的行多态性
// foo : () -<State, E>-> Int (E 是行变量)
type RowVariable = { type: 'rowVar'; name: string };
function unifyRows(row1: EffectRow, row2: EffectRow): Substitution {
// 行统一算法
if (row1.type === 'variable') {
return { [row1.name]: row2 };
}
if (row2.type === 'variable') {
return { [row2.name]: row1 };
}
if (row1.type === 'empty' && row2.type === 'empty') {
return {};
}
// 处理联合和扩展情况...
}
延续管理
// 用于效应处理器的定界延续
interface Continuation<A, B> {
resume(value: A): B;
}
// 多射延续(可以恢复多次)
interface MultiShotContinuation<A, B> extends Continuation<A, B> {
clone(): MultiShotContinuation<A, B>;
}
// 单射延续(只能恢复一次)
interface OneShotContinuation<A, B> extends Continuation<A, B> {
readonly consumed: boolean;
}
// 运行时延续捕获
class ContinuationCapture {
capture<A, B>(
prompt: Prompt,
body: (k: Continuation<A, B>) => B
): B {
// 捕获到提示符的当前延续
const k = captureDelimited(prompt);
return body(k);
}
}
内置效应
// 常见内置效应
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 }
}
}
};
基于效应的优化
// 纯函数可以更积极地优化
function canOptimize(fn: FunctionType): OptimizationLevel {
if (isEmptyRow(fn.effects)) {
return 'pure'; // 完全优化:CSE、记忆化、并行化
}
if (onlyReads(fn.effects)) {
return 'read-only'; // 可以重排序、CSE
}
if (isLocalState(fn.effects)) {
return 'local-state'; // 可以内联,但不能重排序
}
return 'effectful'; // 有限优化
}
// 基于效应的死代码消除
function eliminateDeadCode(expr: Expr): Expr {
const effects = inferEffects(expr);
if (isEmptyRow(effects) && !isUsed(expr)) {
return unit; // 未使用的纯表达式可以消除
}
return expr;
}
工作流程
- 设计效应语法 - 声明、标注、处理器
- 定义效应类型 - 操作、行、多态性
- 实现推断 - 效应推断算法
- 构建效应检查器 - 验证效应标注
- 实现处理器 - 处理器评估/编译
- 添加延续 - 定界延续支持
- 创建内置效应 - 常见效应(IO、State等)
- 生成测试 - 推断、处理器、多态性
应用的最佳实践
- 行多态性用于灵活的效应组合
- 操作和处理器的清晰区分
- 支持推断和标注效应
- 高效的延续表示
- 基于效应的优化机会
- 效应不匹配的良好错误消息
参考文献
- 函数式编程的代数效应:https://www.microsoft.com/en-us/research/publication/algebraic-effects-for-functional-programming/
- Koka 语言:https://koka-lang.github.io/
- Eff 语言:https://www.eff-lang.org/
- 作用域中的效应处理器:https://www.cs.ox.ac.uk/people/nicolas.wu/papers/Scope.pdf
- Frank 语言:https://arxiv.org/abs/1611.09259
目标流程
- effect-system-design.js
- type-system-implementation.js
- concurrency-primitives.js