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

这种带返回结果的有状态函数模式有名称吗?FSharpPlus中有对应抽象吗?

相关问题解答

模式命名

你描述的确实是State monad(状态单子)与Result monad(结果单子)的组合模式,通用函数式编程语境下的标准命名是StateResult单子转换器(Monad Transformer),也常被称为带错误短路的状态折叠模式,在事件溯源领域这类操作通常直接叫做「事件重播折叠」。

FSharpPlus 开箱实现

FSharpPlus 已经提供了完整的对应实现,不需要你自己写计算表达式或折叠逻辑:

  1. 你的步进函数类型'state -> 'event -> Result<'state * 'result, 'error>可以直接适配为库中StateT<'state, Result<'result, 'error>>类型的实例
  2. 配合库内置的traverse函数即可完成你需要的逻辑:按顺序处理所有事件,任意步骤失败直接返回第一个错误,全部成功则返回最终状态和结果集合

参考代码示例:

open FSharpPlus
open FSharpPlus.Data

// 你的业务步进函数
let step (state: int) (event: string) =
    if event.Length > 5 then Error "事件长度超出限制"
    else Ok (state + 1, event.ToUpper())

// 包装为StateT实例
let stepT event = StateT (fun s -> step s event)

// 处理事件列表的入口函数,输出类型为 Result<'state * 'result list, 'error>
let processEvents initialState events =
    traverse stepT events
    |> StateT.run
    |> flip initialState

无第三方依赖的简化实现

如果你不想引入FSharpPlus,也可以用原生F#的列表折叠快速实现同等逻辑:

let foldEvents step initialState events =
    let folder acc event =
        match acc with
        | Error e -> Error e
        | Ok (currentState, results) ->
            match step currentState event with
            | Error e -> Error e
            | Ok (newState, res) -> Ok (newState, results @ [res])
    folder (Ok (initialState, [])) events

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 22:57:03