我有一个t,它具有form int*&lt的元素;摘要>*int。
我想找到该集合的一个元素,例如4*<摘要>*5。
当我尝试使用
时match T with
|(4,_,5) -> Printf.printf "yes"
|(_,_,_) -> Printf.printf "no"
我正在遇到一个错误,上面写着"错误:此表达式具有类型过渡集,但期望类型Loc *'a * loc"
的表达式。如何在集合中找到元素?
集合是抽象的,因此无法匹配模式。在OCAML的标准库集模块中,您可以做的是filter
集合,然后检查is_empty
是否:
Set.(is_empty @@ filter p t)
其中 p
是您的谓词。
我假设您的设置模块称为TSet
,并且您使用的是OCAML标准库集。我还假设您的集合并不称为T
,因为这不是OCAML变量的有效名称。
如果您仅关心是否存在单个匹配值的答案,则可以:
let result =
TSet.exists
(function
| 4, _, 5 -> true
| _ -> false)
t in
if result then print_endline "yes" else print_endline "no"
通常,无论您的谓词是什么,您都可以做
TSet.exists p t
如果您想要的是是/否答案,并且希望能够在集合中所有匹配值的情况下执行任意计算,则必须将fold
或iter
与模式匹配使用。例如,如果您想将所有第一个整数添加在一起,但是只有当最后一个整数为5:
TSet.fold
(fun element accumulator ->
match element with
| x, _, 5 -> x + accumulator
| _ -> accumulator)
t 0
如果您只想在第一个匹配元素上执行计算,则可以在例外进行短路评估。例如:
exception Found of int
try
TSet.iter
(function
| x, _, 5 -> raise_notrace (Found x)
| _ -> ())
t;
None
with Found x -> Some x
最后一个一遍又一遍地笨拙。您可以使用参考和内置Exit
异常来编写多态函数来解决您自己的短路模式匹配搜索的问题。我将其作为练习。
使用raise_notrace
是一个好主意,因为该例外已用于正常流量控制。如果您的程序是有一天启用了堆栈跟踪的一天,则raise_notrace
在抛出异常时会省略堆栈跟踪,如果您的功能经常被调用,则可以使您的程序更快。
供您参考,http://caml.inria.fr/pub/docs/manual-ocaml/libref/set.s.s.html