如何解决SML中else if语句中的"unresolved flex record"?
How to solve "unresolved flex record" in else if statement in SML?
我想找到当前给定节点直接或间接连接到的节点列表。
例如,我有一个节点列表:
[1,2]
和一个元组列表,每个元组代表一条直接边:
[(1,5),(2,4),(4,6)]
所以,我要找的节点是
[1,2,5,4,6]
因为,1接5,2接4,然后,4接6。
为此,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点添加到队列和列表中。然后,我们删除队列的第一个节点,并转到下一个节点。如果一个新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中。
我们一直这样做,直到队列为空并且我们 return 列表。
所以现在,我有一个附加函数,可以将一个列表附加到另一个列表:
fun append(xs, ys) =
case ys of
[] => xs
| (y::ys') => append(xs @ [y], ys')
然后,我有一个名为 getIndirectNodes 的函数,它打算 return 给定节点间接连接到的节点列表,但抛出 "unresolved flex record"。 List1 和 List2 应该有相同的项目。但是,List1 服务于队列,而 list2 服务器作为要 returned 的列表。
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
- 但使用模式匹配是更好的主意。
(该代码还有许多其他问题,但这就是您问题的答案。)
您的一位同学似乎在 中遇到了这个元组问题。
确保在再次问同样的问题之前浏览 Whosebug 问答。
关于获取间接节点,可以通过定点迭代解决
先获取所有直连节点,再获取直连节点的直连节点
然后递归地执行此操作,直到不再有新节点以这种方式出现。
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
自身,即使它们本身不能直接或间接访问。
我试图通过使用 sets 作为数据类型来简化此练习;使用集合类型的实际、高效的实现会更整洁,例如使用平衡二叉搜索树。通过向集合中添加元素更容易查看是否有新节点,因为如果集合中已经包含元素,则在添加元素之前和之后它将等同于自身。
并且我尝试在有意义的时候使用高阶函数。例如,给定一个列表,其中我想对每个元素执行相同的操作,List.map
会生成一个结果列表。但是由于我想做的事情,getDirectNodes (startNode, edges)
生成一个列表,然后 List.map f
生成一个列表列表。所以 List.concat
将其折叠成一个列表。
List.concat (List.map f xs)
这是一件很常见的事情。
我想找到当前给定节点直接或间接连接到的节点列表。 例如,我有一个节点列表:
[1,2]
和一个元组列表,每个元组代表一条直接边:
[(1,5),(2,4),(4,6)]
所以,我要找的节点是
[1,2,5,4,6]
因为,1接5,2接4,然后,4接6。 为此,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点添加到队列和列表中。然后,我们删除队列的第一个节点,并转到下一个节点。如果一个新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中。
我们一直这样做,直到队列为空并且我们 return 列表。
所以现在,我有一个附加函数,可以将一个列表附加到另一个列表:
fun append(xs, ys) =
case ys of
[] => xs
| (y::ys') => append(xs @ [y], ys')
然后,我有一个名为 getIndirectNodes 的函数,它打算 return 给定节点间接连接到的节点列表,但抛出 "unresolved flex record"。 List1 和 List2 应该有相同的项目。但是,List1 服务于队列,而 list2 服务器作为要 returned 的列表。
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
- 但使用模式匹配是更好的主意。
(该代码还有许多其他问题,但这就是您问题的答案。)
您的一位同学似乎在
确保在再次问同样的问题之前浏览 Whosebug 问答。
关于获取间接节点,可以通过定点迭代解决
先获取所有直连节点,再获取直连节点的直连节点
然后递归地执行此操作,直到不再有新节点以这种方式出现。
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
自身,即使它们本身不能直接或间接访问。
我试图通过使用 sets 作为数据类型来简化此练习;使用集合类型的实际、高效的实现会更整洁,例如使用平衡二叉搜索树。通过向集合中添加元素更容易查看是否有新节点,因为如果集合中已经包含元素,则在添加元素之前和之后它将等同于自身。
并且我尝试在有意义的时候使用高阶函数。例如,给定一个列表,其中我想对每个元素执行相同的操作,List.map
会生成一个结果列表。但是由于我想做的事情,getDirectNodes (startNode, edges)
生成一个列表,然后 List.map f
生成一个列表列表。所以 List.concat
将其折叠成一个列表。
List.concat (List.map f xs)
这是一件很常见的事情。