如何解决;“未解决的弹性记录”;在SML中的else if语句中?

如何解决;“未解决的弹性记录”;在SML中的else if语句中?,sml,smlnj,Sml,Smlnj,我想找到当前给定节点直接或间接连接到的节点列表。 例如,我有一个节点列表: [1,2] 和元组列表,每个元组表示一条直边: [(1,5),(2,4),(4,6)] 所以,我要寻找的节点是 [1,2,5,4,6] 因为,1连接到5,2连接到4。然后,4连接到6。 要实现这一点,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点附加到队列和列表中。然后,我们移除队列的第一个节点,并转到下一个节点。如果新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中 我们一直这样做,直

我想找到当前给定节点直接或间接连接到的节点列表。 例如,我有一个节点列表:

[1,2]
和元组列表,每个元组表示一条直边:

[(1,5),(2,4),(4,6)]
所以,我要寻找的节点是

[1,2,5,4,6]
因为,1连接到5,2连接到4。然后,4连接到6。 要实现这一点,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点附加到队列和列表中。然后,我们移除队列的第一个节点,并转到下一个节点。如果新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中

我们一直这样做,直到队列为空并返回列表

现在,我有一个append函数,它将一个列表附加到另一个列表:

fun append(xs, ys) = 
   case ys of 
        [] => xs
    | (y::ys') => append(xs @ [y], ys')
然后,我有一个名为getIndirectNodes的函数,它打算返回给定节点间接连接到的节点列表,但抛出“未解析的flex记录”。清单1和清单2应该有相同的项。但是,List1服务于队列,list2服务器作为要返回的列表

  fun getIndirectNode(listRoleTuples, list1, list2) =
      if list1 = []
          then list2
     else if hd(list1) = #1(hd(listRoleTuples))
        then (
            append(list1,#2(hd(listRoleTuples)) :: []);
            append(list2,#2(hd(listRoleTuples)) :: []);
            getIndirectNode(listRoleTuples,tl(list1),list2)
            )
        else
           getIndirectNode(listRoleTuples,tl(list1),list2)

如果我删除else-If语句,它就可以正常工作。但是,这不是我想要做的。问题出在else-if语句中。我能做些什么来修复它呢?

SML需要确切地知道元组的形状才能解构它。
您可以指定参数的类型-
listRoleTuples:(“a*”a)list
,但是使用模式匹配是一个更好的主意


(这段代码还有很多其他问题,但这就是你问题的答案。)

看来你的一位同学在一次实验中遇到了这个确切的元组问题

在再次提出相同的问题之前,请确保浏览StackOverflow问答

对于获得间接节点,可以通过定点迭代来解决

首先得到所有直接节点,然后得到直接节点中的直接节点

递归地执行此操作,直到不再以这种方式出现新节点

fun getDirectNodes (startNode, edges) =
    List.map #2 (List.filter (fn (node, _) => node = startNode) edges)

fun toSet xs =
    ... sort and remove duplicates ...

fun getReachableNodes (startNodes, edges) =
    let
      fun f startNode = getDirectNodes (startNode, edges)
      val startNodes = toSet startNodes
      val endNodes = toSet (List.concat (List.map f startNodes))
    in
      if startNodes = endNodes
      then endNodes
      else getReachableNodes (startNodes @ endNodes, edges)
    end
这并不能准确地找到间接端点节点;它查找所有可由
startNodes
直接或间接访问的节点,并包括
startNodes
本身,即使它们本身无法直接或间接访问

我试图通过使用集合作为数据类型来简化这个练习;如果使用集类型的实际有效实现,例如使用平衡的二叉搜索树,则会更加整洁。通过向集合中添加元素,可以更容易地看到是否没有新节点,因为如果集合中已经包含元素,那么在添加元素之前和之后,它将与自身等价

当这有意义时,我尝试使用高阶函数。例如,给定一个列表,其中我希望对每个元素执行相同的操作,
list.map
生成一个结果列表。但是由于我想做的事情,
getDirectNodes(startNode,edges)
生成一个列表,然后
list.map f
生成一个列表。因此,
List.concat
将其压缩为一个列表

List.concat (List.map f xs)

这是一件非常常见的事情。

然后
中的顺序是“附加这些列表并放弃结果,然后附加这些其他列表并放弃结果,然后递归”。您需要将结果传递给递归。您只使用了
listRoleTuples
的第一个元素。试图同时在两个列表上递归通常是非常混乱的。尝试将问题分解,这样您只需要在一个列表上递归。(这个问题比乍看起来要棘手得多。考虑重复和循环。)注意,<代码>附录< /代码>已经存在作为<代码> @ <代码>运算符。