我试图编写一个高阶函数选择,该函数选择将f输出为true的元素,然后在列表中输出其值。
例如:
#let f a = if a>8 then true else false;;
pick [1;3;4;9;12;22] f;;
- : int list = [9;12;22]
到目前为止,我已经编写了这段代码,但是它不起作用:
let rec pick f list =
let p1 = f list in
if (List.hd(p1)==true)
then List.hd(p1)::pick List.tl(p1)
else pick List.tl(p1)
错误:此表达式的类型为'a list 但是期望使用'b-> bool#
类型的表达式我该如何更正它以便在列表上使用?
答案 0 :(得分:3)
这是您的代码中的一些问题。
pick f list
,但将其称为pick [list] f
。确保您的参数顺序一致。 =>这是导致您收到错误消息的那一个。f
,而只能在列表的元素上调用。List.hd
或List.tl
。==
用于结构相等,也不要将布尔值与相等使用。if a>8 then true else false
仅应替换为a>8
答案 1 :(得分:1)
使用表达式f list
,您将列表list
传递给函数f
,这不是您想执行的操作。您只想在列表的开头调用f
。
通常,在这种情况下,OCaml程序员将使用模式匹配来解构列表,如下所示(我尚未测试此代码):
let rec pick f list =
match list with
| [] -> []
| h::t -> if f h then h :: pick f t
else pick f t
答案 2 :(得分:0)
列表模块已经包含解决方案,它是功能过滤器。
let f a = a > 8;;
List.filter f [1;3;4;9;12;22];;
- : int list = [9;12;22]
该函数在列表上进行迭代,将用于验证给定谓词的元素存储在累加器中并返回。
标准库包含许多标准方法,例如过滤器,建议您首先查看文档,因为这些功能可以解决大多数问题。
Inria的列表模块文档:
https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html