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

SML中如何向列表追加record triple?求修正similar_names函数错误

SML similar_names函数语法错误及record列表构建问题

问题说明

我在实现SML的similar_names函数时遇到语法错误,搞不懂怎么把record三元组追加到列表里。该函数需求如下:

  • 接收两个参数:字符串列表的列表,以及一个类型为{first:string, middle:string, last:string}的record
  • 通过get_substitutions2函数,以输入record的first字段为匹配项,查找所有替换名
  • 最终输出包含原record及所有替换名对应record的列表

我的代码

fun same_string(s1 : string, s2 : string) =
  s1 = s2
         
fun all_except_option(str, []) = NONE
  | all_except_option(str, x::xs) =
    case same_string(x, str) of
        true  => SOME xs
      | false => 
          let 
            fun build_list(x::xs, str) =
              case all_except_option(str, xs) of
                 NONE => NONE
               | SOME y => SOME(x::y)
          in
            build_list(x::xs, str)
          end

fun get_substitutions2(xss, str) =
  let 
    fun sub([], acc) = acc
      | sub(ys::yss, acc) =
        case all_except_option(str, ys) of
            NONE   => sub(yss, acc)
          | SOME y => sub(yss, y@acc)
  in
    sub(xss, [])
  end

fun similar_names(xss, []) = Empty
  | similar_names(xss, r : {first:string, middle:string, last:string}) = 
    let 
      fun helper (x::xs, acc) =
        case x of
            [] => acc
          | {first=a, middle=b, last=c} => helper(xs, {x, b, c} @ acc)
    in
      case get_substitutions2(xss,a) of
          NONE   => NONE
        | SOME y => helper(y, [])     
    end

错误信息

- foo.sml:32.45 Error: syntax error: inserting  VAL
- foo.sml:33.5-33.7 Error: syntax error: replacing  IN with  EQUALOP
- foo.sml:38.5 Error: syntax error found at END

示例输入

similar_names(
  [["Fred", "Fredrick"], 
   ["Elizabeth", "Betty"],
   ["Freddie", "Fred", "F"]], 
  {first="Fred", middle="W", last="Smith"}
)

预期输出

[{first="Fred", last="Smith", middle="W"}, 
 {first="Fredrick", last="Smith", middle="W"}, 
 {first="Freddie", last="Smith", middle="W"}, 
 {first="F", last="Smith", middle="W"}]

错误分析与修正代码

你的similar_names函数存在多处语法和逻辑错误:

  1. 无效分支与非法值:similar_names(xss, []) = Empty不符合需求(第二个参数应为record),且Empty不是SML合法值
  2. 类型匹配错误:get_substitutions2返回字符串列表,但你在helper里错误地将字符串匹配为record
  3. record构造与列表拼接错误:{x, b, c}是非法的record构造方式,且单个record不能直接用@拼接列表
  4. 未定义变量:case get_substitutions2(xss,a)中的a未定义,需先从输入record中解构提取

修正后的代码:

fun same_string(s1 : string, s2 : string) =
  s1 = s2
         
fun all_except_option(str, []) = NONE
  | all_except_option(str, x::xs) =
    case same_string(x, str) of
        true  => SOME xs
      | false => 
          case all_except_option(str, xs) of
              NONE => NONE
            | SOME y => SOME(x::y)

fun get_substitutions2(xss, str) =
  let 
    fun sub([], acc) = acc
      | sub(ys::yss, acc) =
        case all_except_option(str, ys) of
            NONE   => sub(yss, acc)
          | SOME y => sub(yss, y @ acc)
  in
    sub(xss, [])
  end

fun similar_names(xss, r : {first:string, middle:string, last:string}) = 
  let 
    val {first=orig_first, middle=m, last=l} = r
    val subs = orig_first :: get_substitutions2(xss, orig_first)
    fun helper [] acc = acc
      | helper (name::names) acc = 
          helper names ({first=name, middle=m, last=l} :: acc)
  in
    rev (helper subs [])
  end

修正说明

  1. 移除无效分支:删除不符合需求的空列表匹配分支
  2. 解构输入record:从输入的r中提取原名字、中间名、姓氏,避免重复读取字段
  3. 合并替换名列表:将原名字和所有替换名合并为完整的字符串列表
  4. 正确构建record列表:遍历每个名字构造对应record,用::添加到列表,最后用rev保证输出顺序与预期一致
  5. 简化冗余代码:移除原all_except_option中冗余的build_list函数,直接用case分支处理逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:52:47