You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持短路求值的lazy altAll方法?

实现支持短路求值的lazyAltAll替代Option switch逻辑

你遇到的问题核心是alt.altAll会预先计算传入的整个Option数组,无法做到短路求值——也就是找到第一个Some值后就停止后续计算。下面是实现你想要的lazyAltAll的方案:

实现lazyAltAll函数

我们可以基于fp-ts的Alt类型,自己实现一个支持懒加载的版本,通过函数包裹每个Option生成逻辑,只有在需要的时候才执行:

import * as O from 'fp-ts/Option'
import type { Alt } from 'fp-ts/Alt'

const lazyAltAll = <A>(alt: Alt<O.Option>) => 
  (initial: O.Option<A>) => 
  (options: Array<() => O.Option<A>>): O.Option<A> => {
    return options.reduce((acc, getOption) => {
      // 如果已经找到Some值,直接短路返回
      if (O.isSome(acc)) return acc
      // 否则执行当前函数生成Option,合并到累积值中
      return alt.alt(acc)(getOption())
    }, initial)
  }

使用示例

现在你可以按照预期的方式编写foo函数,所有Option生成逻辑都会延迟到需要时执行,且找到第一个Some后就停止后续计算:

function foo(a: number) {
  return lazyAltAll(O.Alt)<string>(O.none)([
    () => O.fromPredicate(() => a >= 85)('A'),
    () => O.fromPredicate(() => a >= 75)('B'),
    () => O.fromPredicate(() => a >= 60)('C'),
    () => O.some('D'),
  ])
}

实现逻辑说明

  • 用reduce遍历选项数组,维护一个累积的Option值
  • 每次迭代先检查累积值是否为Some,如果是直接返回,实现短路
  • 只有当累积值为None时,才调用当前的函数生成新的Option,再通过alt.alt合并
  • 这种方式避免了预先计算所有Option,完全符合你想要的短路求值逻辑

递归实现版本(可选)

如果你更喜欢递归风格的实现,也可以用下面的写法,逻辑更直观:

const lazyAltAllRecursive = <A>(alt: Alt<O.Option>) => 
  (initial: O.Option<A>) => 
  (options: Array<() => O.Option<A>>): O.Option<A> => {
    if (options.length === 0) return initial
    const currentOption = options[0]()
    return O.isSome(currentOption) 
      ? currentOption 
      : lazyAltAllRecursive(alt)(initial)(options.slice(1))
  }

内容的提问来源于stack exchange,提问作者Mxcpanel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:31:56