如何解决尝试检查 Ocaml 列表中的键值对
我正在尝试查看列表列表中是否存在某个名称,如果存在,我将返回与该名称关联的值。我将值(字符串、整数、布尔值)绑定到一个字符串并将它们存储在一个环境中,该环境由整个列表中的每个列表表示。
let rec lookup key envlist = match envlist with
|[] -> None
|hd::tl -> lookupaux key hd
in
let rec lookupaux name curenvlist = match curenvlist with
|[] -> None
|(n,v)::t -> if n = name then Some v else lookupaux name t
我知道这是无效的,但这是我目前想到的。任何帮助都是极好的。另外,我试图先阅读整个顶行,然后是下一行,依此类推。
解决方法
迭代逻辑不错,就是不明白需要两个函数?
在 List module of OCaml 中,有一些函数可以帮助您。例如,OCaml List 模块中的一些函数可能会对您有所帮助,例如,由于 OCaml 4.10.0
,您可以使用 find_map
:
let lookup searched_key envlist =
List.find_map (fun (key,value) ->
if key = searched_key then Some value else None
) envlist
或者我们使用find_opt
,它不那么直接,但具有更长的优点(OCaml 4.05
):
let lookup searched_key envlist =
(* First,get an option *)
List.find_opt (fun (key,_) -> key = searched_key) envlist
(* Now,using Option,you can fetch only the value
https://ocaml.org/api/Option.html#VALmap (since 4.08) *)
|> Option.map snd
(当然,如果您使用较旧的 OCaml 版本,您可以手动解构结果选项,以免依赖模块选项)。
另一方面,如果您真的想构建手动递归,显然也可以遵循与您提出的方案接近的方案:
let rec lookup searched_key envlist =
match envlist with
| [] -> None
| (key,value) :: tail ->
if key = searched_key then Some value
else lookup searched_key tail
您还可以使用 when
(守卫)在模式级别设置条件:
let rec lookup searched_key envlist =
match envlist with
| [] -> None
| (key,value) :: _ when key = searched_key -> Some value
| _ :: tail -> lookup searched_key tail
但是,如果您查看代码,您可能会因为必须通过递归重复您正在寻找的键而感到恼火……即使它在执行函数时是不变的?因此,我们可以使用我们函数内部的辅助函数,以避免每次都必须传递密钥。
let lookup searched_key =
let rec aux = function
| [] -> None
| (key,value) :: _ when key = searched_key -> Some value
| _ :: tail -> aux y tail
in aux (* [aux] will return a function that take a list *)
编辑:
我忽略了您必须在列表列表中找到一个键的要点,现在我明白为什么需要两个函数了。 这与您的建议非常接近。
let lookup searched_key =
let rec find_value = function
| [] -> None
| (key,value) :: _ when key = searched_key -> Some value
| _ :: tail -> find_value y tail
in
let rec aux = function
| [] -> None
| x :: xs -> begin
(* begin/end or parenthesis are mandatory for
nested pattern matching *)
match find_value x with
| None -> (* if we don't find the key,we continue on the tail*)
aux xs
| Some x -> Some x
end
in aux
我认为您的程序犯的唯一错误是它没有检查是否在列表中找到了值。所以它遍历列表,甚至找到了键。您只需要在发现某些东西(或未找到)时处理这种情况。就像在我的代码中一样。
第二次编辑
使用表单 f = function ...
可能不清楚,所以这里有一个没有快捷方式的版本:
let lookup searched_key envlist =
let rec find_value list =
match list with
| [] -> None
| (key,value) :: _ when key = searched_key -> Some value
| _ :: tail -> find_value y tail
in
let rec aux envlist =
match envlist with
| [] -> None
| x :: xs -> begin
(* begin/end or parenthesis are mandatory for
nested pattern matching *)
match find_value x with
| None -> (* if we don't find the key,we continue on the tail*)
aux xs
| Some x -> Some x
end
in aux envlist
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。