已发布 上游基线 bf46254 原文 ↗ 在 GitHub 编辑

Effect 类型

理解 Effect 生态中的 Effect 类型:它为带 effect 的计算提供类型安全的成功值、错误与需求处理,并用于建模不可变、惰性的工作流。

Effect 类型是对惰性执行的工作流或操作的描述。也就是说,当你创建一个 Effect 时,它并不会立即运行,而是定义了一个可能成功、失败,或者需要一些额外上下文才能完成的程序。

下面是 Effect 的一般形式:

         ┌─── Represents the success type
         │        ┌─── Represents the error type
         │        │      ┌─── Represents required dependencies
         ▼        ▼      ▼
Effect<Success, Error, Requirements>

这个类型表明一个 effect 会:

  • 成功并返回一个 Success 类型的值
  • Error 类型的错误失败
  • 执行时可能需要 Requirements 类型的特定上下文依赖

从概念上讲,你可以把 Effect 看作下面这种函数类型的「带 effect」版本:

type Effect<Success, Error, Requirements> = (
  context: Context<Requirements>,
) => Error | Success

不过,effect 实际上并不是函数。它们可以建模同步、异步、并发以及需要管理资源的计算。

不可变性Effect 值是不可变的,Effect 库中的每个函数都会产生一个新的 Effect 值。

对交互建模。这些值本身不执行任何动作,它们只是建模或描述带 effect 的交互。

执行Effect 可以由 Effect 运行时系统 执行,后者会把它解释为与外部世界的实际交互。 理想情况下,这次执行发生在你应用中的单一入口点,例如发起各种 effect 操作的 main 函数。

类型参数

Effect 类型有三个类型参数,含义如下:

参数说明
Success表示 effect 执行成功时所产生的值的类型。如果该类型参数是 void,说明这个 effect 不产生任何有用的信息;如果它是 never,说明这个 effect 会永远运行下去(或者直到失败)。
Error表示执行 effect 时可能发生的预期错误。如果该类型参数是 never,说明这个 effect 不会失败,因为不存在 never 类型的值。
Requirements表示 effect 执行所需的上下文数据。这些数据存储在一个名为 Context 的集合中。如果该类型参数是 never,说明这个 effect 没有任何需求,Context 集合是空的。
Type Parameter Abbreviations

在 Effect 生态中,你经常会遇到 Effect 的类型参数被分别简写为 AER。这只是成功值类型 AError 和 Requirements 的简写。

提取推断出的类型

借助工具类型 Effect.SuccessEffect.ErrorEffect.Context,你可以从一个 effect 中提取出相应的类型。

示例(提取 Success、Error 与 Context 类型)

import { Effect, Context } from "effect"

class SomeContext extends Context.Tag("SomeContext")<SomeContext, {}>() {}

// Assume we have an effect that succeeds with a number,
// fails with an Error, and requires SomeContext
declare const program: Effect.Effect<number, Error, SomeContext>

// Extract the success type, which is number
type A = Effect.Effect.Success<typeof program>

// Extract the error type, which is Error
type E = Effect.Effect.Error<typeof program>

// Extract the context type, which is SomeContext
type R = Effect.Effect.Context<typeof program>