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

SML/NJ实现单子解析库时datatype与type别名未按预期工作

问题解答

核心原因

你代码中先后对'a parse_result做了两次定义,SML中后出现的同名类型定义会覆盖之前的定义:

  1. 第一次使用type声明别名:type 'a parse_result = 'a parse_data list,此时该类型确实是('a * char list) list的等价别名
  2. 后续使用datatype定义代数数据类型时,再次使用了parse_result作为类型名,直接覆盖了之前的别名定义。且本次定义中ParseSuccess of 'a parse_result递归引用的是新定义的ADT本身,而非你预期的列表类型,因此会出现列表和ADT类型不匹配的报错。

解决方案

只要给列表别名和结果ADT设置不同的名称,避免重名覆盖即可,示例定义如下:

type 'a parse_data = ('a * char list);
(* 给成功返回的列表类型单独设置别名,不和ADT重名 *)
type 'a parse_success = 'a parse_data list;
type 'a parser = char list -> 'a parse_success;

(* 结果ADT使用独立名称 *)
datatype 'a parse_result = ParseFailure
                         | ParseSuccess of 'a parse_success;

调整后使用方式如下:

(* 标注为parse_success即可匹配列表类型 *)
val success_data = [("a", [#"a"]), ("b", [#"b"])] : string parse_success;
(* 构造ADT时使用parse_result类型 *)
val final_result = ParseSuccess success_data : string parse_result;

你之前修改定义后可以正常运行,本质是直接将ADT构造子的参数指定为列表类型,规避了重名覆盖的冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:36:04