【问题标题】:How can I access an element in a datatype list of SML?如何访问 SML 数据类型列表中的元素?
【发布时间】:2017-02-19 03:37:07
【问题描述】:

我有两个定义的数据类型

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

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

我正在编写一个函数,get_edges,它返回一个列表,其中包含与图中给定顶点 vi 相关的所有边。对于所有 vj ∈ L,边的形式为 (vi, vj),来自邻接表 V (vi, L)。边的顺序与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

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

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

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

    你可以写一对访问函数:

    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

    【讨论】:

    • fun get_edges(i,G[V(j,k)::tl]) = if i = j then expand(V(j,k)) else get_edges(i,G[tl]); get_edges(2, G [ V(0, [1]), V(1, [0]), V(2, []) ] ) ; 感谢您的帮助,我正在尝试根据您的理解编写 get_edges 部分,但我仍然无法无错误地运行代码,是我还在犯错?
    • 差不多了:fun get_edges(i,G(V(j,k)::tl)) = if i = j then expand(V(j,k)) else get_edges(i,G tl); (注意前两个方括号被括号替换,后两个被删除——(j,k)::tl)tl 已经是列表了)。您可能应该添加一个子句来处理模式get_edges(i, V []) 来处理图中的孤立节点。
    • 我的意思是——你应该处理get_edges (i, G []) 的情况,它对应于i 不在图表中的情况。您可以认为这是一个错误,甚至可以保持原样,但我倾向于编写 SML 代码,以便尽可能避免出现非详尽匹配警告。
    • @JohnColeman:是的,这些“并非详尽无遗”的警告对于了解使用新构造函数扩展数据类型时需要注意哪些代码非常有用。
    • 帮了大忙~非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多