如何访问 SML 数据类型列表中的元素?

How can I access an element in a datatype list of SML?

我有两个定义的数据类型

datatype adj = V of int * int list;
datatype graph = G of adj list;

adj是一个顶点的信息,int是id,int list是相邻顶点id的列表

我正在编写一个函数,get_edges return 是图中给定顶点 vi 的所有边的列表。对于来自邻接表 V (vi, L) 的所有 vj ∈ L,边的形式为 (vi, vj)。边的顺序与L中vj的顺序相同。

val get_edges = fn : int * graph -> (int * int) list

例如

get_edges(0, G [V(0, [1]), V(1, [0])]); 
val it = [(0,1)] : (int * int) list

但是,我不知道如何访问图中的元素以便可以 return 边缘,有什么想法吗?

模式匹配用于获取数据类型的部分。

你可以写一对访问函数:

fun node (V(i,_)) = i;
fun neighbors (V(_,nodes)) = nodes;

然后,例如:

- val a_list = V(0,[2,3,4,7]);
val a_list = V (0,[2,3,4,7]) : adj
-
- node a_list;
val it = 0 : int
-
- neighbors a_list;
val it = [2,3,4,7] : int list

实际中很少需要写这样的访问函数。相反,您只需在设计用于您的类型的任何函数中直接使用模式匹配。

为了说明在这种情况下这是如何工作的,我们可以定义一个辅助函数(这将在您的主函数中很有用):

fun expand (V(i,[])) = []
|   expand (V(i, node::nodes)) = (i,node) :: expand (V(i,nodes));

expand 的类型为 fn : adj -> (int * int) list

例如:

- expand(V(0,[2,3,4,7]));
val it = [(0,2),(0,3),(0,4),(0,7)] : (int * int) list

有了这样的功能和模式匹配的思想,你应该可以实现get_edges