SML 中的数据类型和类型未按预期工作

Posted

技术标签:

【中文标题】SML 中的数据类型和类型未按预期工作【英文标题】:datatype and type in SML not working as intended 【发布时间】:2022-01-04 04:04:09 【问题描述】:

我正在尝试基于monadic parsing paper 实现一个小解析库。我想用 SML(NJ) 来做,因为我正在学习 SML。

这是我目前所拥有的:

type 'a parse_data = ('a * char list);
type 'a parse_result = 'a parse_data list;

type 'a parser = char list -> 'a parse_data list;

datatype 'a parse_result = ParseFailure
                         | ParseSuccess of 'a parse_result;

然后我尝试如下使用它:

ParseSuccess ([("a", [#"a"]), ("b", [#"b"])]: string parse_result);

这给出了以下错误:

stdIn:21.15-21.66 Error: expression doesn't match constraint [tycon mismatch]
  expression: (string * char list) list
  constraint: string parse_result
  in expression:
    ("a",#"a" :: nil) :: ("b",#"b" :: nil) :: nil: string parse_result

我认为这很奇怪,因为我认为我已经使用 type 声明将 ('a * char list) list'a parse_result 别名了。所以我尝试更深入地研究这个问题并尝试以下方法:

([("a", [#"a"]), ("b", [#"b"])]: string parse_result);

又报错了,现在符合预期:

stdIn:22.2-22.53 Error: expression doesn't match constraint [tycon mismatch]
  expression: (string * char list) list
  constraint: string parse_result
  in expression:
    ("a",#"a" :: nil) :: ("b",#"b" :: nil) :: nil: string parse_result

所以我尝试定义 datatype 而不给 parse_result 进行类型别名,如下所示:

datatype 'a parse_result = ParseFailure
                         | ParseSuccess of ('a * char list) list;

然后突然就起作用了:

([("a", [#"a"]), ("b", [#"b"])]);
val it = [("a",[#"a"]),("b",[#"b"])] : (string * char list) list
- ParseSuccess [("a", [#"a"]), ("b", [#"b"])];
val it = ParseSuccess [("a",[#"a"]),("b",[#"b"])] : string parse_result

我不明白,为什么它不接受我的类型别名 string parse_result 代替 (string * char list) list。那不应该工作吗?我如何定义'a parse_result 才能使用它而不是('a * char list) list

我的 SMLNJ 版本是:Standard ML of New Jersey v110.79 [built: Sat Oct 26 12:27:04 2019]

【问题讨论】:

为什么类型别名与数据类型同名? ?:/ @AndreyTyukin 经过数小时寻找可能出现的问题后,我一定是失明了。谢谢你!当我更改名称时,它可以工作。你能把它变成答案吗?还有什么我做错了吗? 您可以回答自己的问题,作为对未来寻求答案者的服务。 @Chris 谢谢。现在就这样做了。很快标记为解决方案。 【参考方案1】:

错误在于datatype 的命名。它与之前定义的type 同名。一旦它被重命名,错误就消失了。工作代码是:

type 'a parse_data = ('a * char list);
type 'a parse_result = 'a parse_data list;

type 'a parser = char list -> 'a parse_result;

datatype 'a result = ParseFailure
                   | ParseSuccess of 'a parse_result;

【讨论】:

您可能希望将此代码包装在“Parse”结构中,而不是在名称上添加“parse”。 我认为这是个好建议。不过,我仍然需要学习结构。目前正在研究 ML 编程的元素,但尚未了解它们:)

以上是关于SML 中的数据类型和类型未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

SML 比较数据类型列表和 hd() tl() 函数

PHP 中的 file_exists 未按预期工作

在 sql server 中未按预期实现使用 round 函数的截断

SQL Server CASE 表达式未按预期计算

Mysql:使用左连接选择未按预期工作

为啥 foldl 签名是管道而不是 SML 中的元组类型?