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

SML中如何将常规seq转换为biseq?

单向序列转双向序列的问题与解决

问题背景

用户定义了两种序列数据类型:

双向序列(biseq)

datatype direction = Back | Forward; 
datatype 'a biseq =   bNil 
                    | bCons of 'a * (direction -> 'a biseq);

常规单向序列(seq)

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq);

用户尝试编写转换函数将seq转为biseq,代码如下:

fun new Nil = bNil
  | new (Cons (x, xf)) =
    bCons (x, fn direction => new (xf ()));

该函数无法正常工作,核心原因是单向序列seq仅能向前获取下一个元素,没有记录前序节点的信息,导致转换后的biseq无法响应Back方向的遍历请求。

解决方案

要实现正确转换,需要在构建biseq时同步维护当前节点的前序信息。由于原序列是单向的,我们只能在遍历过程中记录已走过的节点,以此支持回溯操作。

通过辅助函数实现,该函数同时接收当前处理的单向序列和已遍历元素的列表(作为前序节点来源):

fun seq_to_biseq_helper Nil _ = bNil
  | seq_to_biseq_helper (Cons(x, xf)) prev =
    bCons(x, fn
        Forward => seq_to_biseq_helper (xf()) (x :: prev)
      | Back => case prev of
                   [] => bNil  // 处于首节点,无前置元素
                 | y :: ys => seq_to_biseq_helper (Cons(y, fn () => seq_to_biseq_from_list ys)) ys
    )
and seq_to_biseq_from_list [] = Nil
  | seq_to_biseq_from_list (h :: t) = Cons(h, fn () => seq_to_biseq_from_list t);

// 对外暴露的转换入口函数,初始前序列表为空
fun seq_to_biseq s = seq_to_biseq_helper s [];

逻辑说明

  • Forward方向处理:继续遍历原单向序列,同时将当前元素加入前序列表,让后续节点可以通过该列表回溯到当前节点。
  • Back方向处理:将前序列表的首个元素作为新的当前节点,把剩余前序元素重新构建为单向序列,作为新节点的Forward指向(回到之前的当前节点),以此实现双向遍历的闭环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:42:52