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

时间:2016-10-10 16:42:20

标签: sml smlnj

我有两种已定义的数据类型

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

adj是顶点的信息,int是id,int列表是邻近顶点id的列表

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

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

e.g。

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

但是,我不知道如何访问图表中的元素以便我可以返回边缘,任何想法?

1 个答案:

答案 0 :(得分:2)

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

您可以编写一对访问功能:

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

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

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

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