Effect 里 map 和 flatMap 怎么选?
在 map 里返回一个 Effect,你会得到 Effect<Effect<...>>,里面那层永远不会被运行。
函数返回普通值就用 map,返回另一个 Effect 就用 flatMap。 用错了不会静默通过,因为类型会变成「Effect 里套着 Effect」,一眼就能看出来。
这里的 Effect 指 Effect<A, E, R>,一段对计算的描述而不是已经发生的结果,细节见 为什么我用 Effect。map、flatMap、tap、andThen 都是用 pipe 串起来的小变换,下面按它们的分工逐个讲。
pipe 是什么,怎么写?
pipe 在 v4 里是 Effect 值上的方法,写成 value.pipe(f, g, h),就是依次把 value 交给 f、g、h。它也可以用于任何其他值。
const piped = Effect.succeed(2).pipe(
Effect.map((n) => n * 2),
Effect.flatMap((n) => Effect.succeed(String(n))),
Effect.tap((s) => Effect.log(s)),
Effect.andThen((s) => Effect.succeed(s.length))
)map、flatMap、tap、andThen 各管什么?
map:变换成功值,函数返回普通值flatMap:变换成功值,函数返回另一个 Effect(需要再运行一步)tap:做一个副作用(日志、指标),但保留原来的成功值andThen:对「接下来做什么」的宽松写法,既接受返回值的函数,也接受返回 Effect 的函数
map 里返回了 Effect 会怎样?
结果是 Effect<Effect<...>>,里面那层永远不会被运行。这是个典型的错用,好在类型会暴露它。把 map 换成 flatMap 就行。
步骤多了,还该用 pipe 吗?
多步、有中间变量、有条件分支时,Effect.gen 更顺手;pipe 更适合在单个 Effect 上叠加一连串小变换或横切行为。两者怎么分工,见 怎么用 Effect.gen 写出第一段 Effect 程序。
本文的 API 与行为描述全部取自教程原章节,代码没有在写作时重新运行。原章节只提到 Effect v4,没有给出具体版本号,写法以你安装的版本为准。