我是 SML 的新手,我想更新我的函数,使其有两个输出:一个列表 AND 1 或 0。这里提出了该函数: SML: Remove the entry from the List 。它返回一个没有包含“elem”行的更新列表。

fun removeElem elem myList = filter (fn x => x <> elem) myList

如果原始数据已被删除,该函数应返回一个新列表 AND 1。否则,它应该返回一个旧列表 AND 0。

任何提示或示例都受到高度赞赏。谢谢。

最佳答案

请注意,所有 SML 函数都采用单个输入并返回单个输出。相反,考虑返回一个包含新列表的元组和一个指示是否删除了任何元素的标志。一种可能性是使用标准基础中的几个函数来测试 elem 是否在 myList 中,并构建一个由该元组和问题中显示的 filter 结果组成的元组。测试可能如下所示:

Option.isSome (List.find (fn x => x = elem) myList)

有更简洁的写法,但它显示了这个想法。请注意,它返回的是 bool 而不是 int ;这更精确,所以我不会转换为问题中要求的整数。

上面的一个缺点是它需要遍历列表两次。为避免这种情况,请考虑函数必须返回的类型:没有 elem 的列表元组和显示是否已删除任何 elem 的标志。然后我们可以编写一个函数,它接受一个新值和一个(有效的)元组,并返回一个有效的元组。一种可能:
fun update(x, (acc, flag)) = if x = elem then (acc, true) else (x :: acc, flag)

然后我们可以将 update 一一应用于 myList 的每个元素。由于我们希望列表的顺序保持不变,除了删除的元素之外,我们应该从右到左处理 myList,将结果累加到一个最初为空的列表中。函数 foldr 将直接执行此操作:
foldr update ([], false) myList

但是,foldr 高阶函数中隐藏了很多逻辑。

要将其用作学习练习,我建议使用此问题以几种方式实现该功能:
  • 作为递归函数
  • 作为尾递归函数
  • 使用高阶函数 foldlfoldr

  • 了解这些版本之间的差异将有助于了解 SML 的工作原理。对于每个版本,让类型指导您。

    关于list - SML:具有多个输出的功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8560300/

    10-12 14:12