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

SML实现字符串转大写报错:类型不匹配问题求助

解决SML字符串转大写的类型匹配问题

作为SML和函数式编程新手,你遇到的类型不匹配问题主要是递归逻辑和参数处理上的小失误,咱们一步步拆解修复:

你的代码核心问题分析

先看你写的递归函数toCaps和调用逻辑:

fun toCaps (acc, nil: char list) = acc 
  | toCaps (acc, h::t: char list) = toCaps ((acc::t), [Char.toUpper(h)])

还有调用时的toCaps(ex, []:char list)

这里有两个关键错误:

  1. 参数顺序完全搞反:函数定义里第一个参数是用来积累结果的累加器acc(初始应该是空列表),第二个参数是待处理的字符列表。但你调用时把待处理的ex放在了第一个位置,空列表放在第二个位置,直接触发了类型不匹配。
  2. 列表操作不符合语法:acc::t是错误的写法——::操作符要求左边是单个元素,右边是列表,但acc本身就是char list,t也是char list,类型检查器自然会报错。正确的做法是把大写后的单个字符Char.toUpper(h)加到累加器acc的前面,形成新的累加器。

另外还有个隐藏问题:直接把字符加到累加器前会得到逆序的列表,最后需要反转才能得到正确顺序的字符串。

修正后的完整代码

把这些问题修复后,代码就能正常运行了:

fun allCaps (str) = 
    let 
        val ex = explode(str) 
        fun toCaps (acc, nil: char list) = rev acc  (* 反转累加器,恢复正确顺序 *)
          | toCaps (acc, h::t: char list) = toCaps (Char.toUpper(h) :: acc, t)  (* 将大写字符加入累加器,递归处理剩余列表 *)
    in 
        implode(toCaps([], ex))  (* 初始累加器为空,传入待处理的字符列表 *)
    end;

测试一下:allCaps "hello sml" 会返回 "HELLO SML"。

更简洁的函数式写法

作为函数式编程新手,你可以试试用SML内置的高阶函数map来简化代码——它能把一个函数应用到列表的每个元素上,完美适配这个场景:

fun allCaps str = implode (map Char.toUpper (explode str));

这种写法更贴合函数式编程的风格,也避免了手动写递归容易踩的坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:16:44