sml - 如何在 SML 中使用 foldr 解析列表
问题描述
假设我有一个清单:
type myList = (string * int) list;
我想使用 foldr 找到这个列表的特定元素,比如:
fun findElement (element : string) (list : myList) : int result =
if needed_element is equal current_list_element then return current_list_element
else continue checking the rest of the list
else return -1
我该怎么做呢?
解决方案
编写伪代码真的很有帮助。
明确确定此函数的类型也是非常有帮助的,例如:
val findElement = fn : string -> myList -> ?
函数应该返回什么类型?在您编写的伪代码int result
中,但result
不能作为标准 ML 中的内置类型构造函数使用。那么它应该是什么?int
? 如果没有匹配的元素怎么办,您如何区分任何特定结果和“无结果”?你有什么选择?
尝试在不先使用的情况下解决此问题foldr
。
由于扫描列表意味着沿其结构递归,因此您可以使用模式匹配编写此函数,其中您将模式分为一个匹配空列表和一个匹配非空列表:
fun lookup needle [] = ?
| lookup needle ((key, value) :: haystack) =
if ?
then ?
else ?
- 条件必须
needle
与每一对的某些东西进行比较,直到匹配。您如何比较 SML 中的两个相等值? - 当条件满足时,不需要进行进一步的递归,所以可以返回一个值。如何在 SML 中返回一些东西?
- 当条件不满足时,通过
lookup
调用自身继续搜索haystack
。称自己是指lookup
在“”之后的身体内部else
。它应该用什么参数来调用自己?
了解基本的递归函数是理解的先决条件foldr
。此时,请尝试阅读有关foldr
. 我找不到任何专门针对此的好的开放材料,因此我会查找您可用的任何书本形式的学习材料。
就与表达相关的挑战lookup
而言foldr
:
foldr
找到元素时不会停止递归。- 您可以通过抛出异常并捕获它来停止它。这有点棘手。
- 您可以让它循环到最后并保留找到的第一个元素。这有点低效。
模板可能如下所示:
fun lookup needle haystack =
foldr (fn ((key, value), acc) => ?) ? haystack
或者您可以在fn ... => ?
本地命名匿名函数:
fun lookup needle haystack =
let fun go ((key, value), acc) = ?
in foldr go ? haystack
end
这里?
指的是lookup
返回的类型的值。
无论您使用手动递归还是foldr
.
推荐阅读
- cpu-architecture - SIMD 编程:数据结构布局的混合方法
- javascript - 如何设置参数有多个斜杠的快速路由?
- react-native - React Native:使用 ScrollView 修复屏幕底部的 TextInput
- eclipse - 在 Eclipse 中找不到 mvn 命令,但可以在终端上使用
- tensorflow - 两个连续图像的 tf.keras 损失
- jdbc - 如何使用 JDBC Driver 连接 GCP 存储桶
- debugging - 为什么 Juno 调试器会尝试在某个随机目录中搜索文件?
- javascript - 表单中的复选框验证
- apache-spark - 获取所有崩溃的 Spark Yarn Job 日志
- c - 构建 make 文件 arm 微控制器