什么是代数效应?
代数效应(Algebraic Effects)是一种用于描述和管理副作用(如状态、异常、IO 等)的方法,属于函数式编程语言中的一种控制结构和抽象机制。它的核心目标是将副作用与程序的主逻辑解耦,从而使程序更容易理解、组合与测试。
algebraic effects 难以理解,主因还是翻译的锅:大部分文章将其译作『代数效应』,实际上它表达的含义大致是『可以当做参数传递的副作用』。
一句话解释
代数效应是一种将副作用声明为操作,并通过处理器来解释这些操作的机制。
举个例子
假设你有这样一个函数:
javascript
function getUserInput() {
const name = prompt("What's your name?");
return name;
}这个函数显然有副作用:prompt() 依赖浏览器,并阻断执行。 如果用 Algebraic Effects 风格来写,逻辑会被分成两部分:
- 声明副作用(写逻辑)
javascript
function* getUserInput() {
const name = yield { type: "PROMPT", message: "What's your name?" };
return name;
}这段代码不直接执行 prompt,而是**发出一个“效果”**请求,告诉运行环境:“我想获取用户输入”。
- 提供副作用解释器(运行逻辑)
js
function runEffect(gen) {
const iterator = gen();
const { value, done } = iterator.next();
if (value.type === "PROMPT") {
const userInput = prompt(value.message);
const result = iterator.next(userInput);
return result.value;
}
}通过以上方式:
- 逻辑(做什么) 与 执行(怎么做) 被完全分离。
- 副作用可以被拦截、模拟、测试、组合。
代数效应的优点
- 解耦副作用:副作用与主逻辑分离。
- 组合性:轻松地组合不同的副作用,而不需要担心它们之间的相互影响。
- 可测试性:轻松地测试副作用,而不需要依赖于实际的副作用实现。
- 可扩展性:轻松地添加新的副作用,而不需要修改现有的代码。
- 简化错误处理:简化错误处理,因为我们可以将错误处理逻辑与主逻辑分离。
- 更好的抽象:提供了一种更好的抽象方式来处理副作用,使得代码更具可读性和可维护性。
