sml - 在 SML 中使用记录作为函数参数
问题描述
SML 中没有得到太多关注的一个主题是“记录”。
我想知道如何处理函数中的记录(作为参数或返回值)。我知道我们可以使用#
运算符来获取记录的元素。但是我应该如何将记录传递给函数?是否有特殊的模式匹配?
我努力了:
fun foo r = #1 r;
它以以下错误结束:
Error: unresolved flex record
(can't tell what fields there are besides #1)
我没有在网上找到任何用 SML 解释这部分记录的指南。
我也试过:
fun foo {1=2,2=3} = 5;
并发现元组实际上是记录的语法糖。当然,我得到了match
警告,但至少这次它奏效了。真正的问题是如何处理“通用”记录。查看一些示例或参考有关该主题的指南可能会有所帮助。
还可以查看有关这些函数签名的解释(正如我提到的那样,记录{1=2,2=3}
会得到不同的签名{a=2,b=3}
)。
解决方案
SML 中没有得到太多关注的一个主题是“记录”。
我不确定你是什么意思。SML 的标准教科书通常涵盖这一点。例如,ML for the Working Programmer,第 2 版。第 2 章,名称、功能和类型,第 28 页及以上涵盖了它们。本书以 PDF 格式免费提供,因此您可以根据需要阅读本章。
如果您阅读第 2 章,第 2 页。34 它涵盖了记录模式:
- val richardIII =
{ name = "Richard III"
, born = 1452
, crowned = 1483
, died = 1485
, quote = "Plots have I laid..."
};
> val richardIII =
{born = 1452, crowned = 1483, died = 1485, name = "Richard III",
quote = "Plots have I laid..."} :
{born : int, crowned : int, died : int, name : string, quote : string}
- val { name = richard_name, died = richard_died, ... } = richardIII;
> val richard_name = "Richard III" : string
val richard_died = 1485 : int
这些记录模式也可以在函数参数中使用。
我建议您阅读有关此主题和其他主题的 SML 教科书。
StackOverflow 是一种糟糕的复制格式。
真正的问题是如何处理“通用”记录
根据您所说的通用记录的含义,SML 可能无法做到这一点。
例如,您可以定义函数
- fun f { x, y } = x + y;
> val f = fn : {x : int, y : int} -> int
但是,如果您尝试定义一个从任意记录中提取x
和而不指定剩余记录类型的记录,y
- fun f { x, y, ... } = x + y;
! Toplevel input:
! fun f { x, y, ... } = x + y;
! ^^^^^^^^^^^^^
! Unresolved record pattern
而如果您指定了记录的类型,
- fun f ({ x, y, ... } : { x : int, y : int, z : int }) = x + y;
> val f = fn : {x : int, y : int, z : int} -> int
或等效地通过类型别名,
- type coord = { x : int, y : int, z : int };
> type coord = {x : int, y : int, z : int}
- fun f ({ x, y, ... } : coord) = x + y;
> val f = fn : {x : int, y : int, z : int} -> int
那么这与使用#x
and一样好#y
:
- fun f (coord : coord) = #x coord + #y coord;
> val f = fn : {x : int, y : int, z : int} -> int
并且没有任何类型的注释或推断,这也将无法识别特定的记录类型:
- fun f coord = #x coord + #y coord;
! Toplevel input:
! fun f coord = #x coord + #y coord;
! ^^
! Unresolved record pattern
所以 SML 不处理这种意义上的通用记录,即使在技术上允许在一种语言中这样做也是可能的。也许这不是你追求的意义。也许记录模式正是您所需要的。我会让你深入研究教科书材料并解决这个问题。
更新:正如 Andreas Rossberg 所建议的,我对示例进行了一些简化。
推荐阅读
- git - 从本地 git 文件夹同步到远程文件夹
- reactjs - React 路由器未从 public/index.html 加载脚本
- python-3.x - 创建数据框,其中每一行由另一个数据框的列名和值组成
- java - 如何在主java中调用函数Keypress
- python - Python即时从应用程序获取文件(不将其保存在文件系统中)
- python - 多处理 - 占用所有 CPU 内核
- c# - 从 3 个不同格式的不同文本文件中读取数据
- regex - regex for logstash.conf input filter path
- javascript - 拒绝连接!硒服务器是否在边缘启动了守夜
- amazon-web-services - 错误地禁用了 ec2-user ssh 访问