首页 > 解决方案 > 在 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 中没有得到太多关注的一个主题是“记录”。

我不确定你是什么意思。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

那么这与使用#xand一样好#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 所建议的,我对示例进行了一些简化。


推荐阅读