[英]OCaml error filter list using higher order functions
所以我有这个练习:
filter (fun x -> x = 0) [(1,0);(2,1);(3,0);(4,1)];;
result int list [1;3]
因此,基本上,您必须将x与列表中的第二个数字匹配,如果相同,则使用第一个数字创建新列表。
我的解决方案,但错了
let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [];;
我想尝试代码时收到以下错误:
错误:此表达式的类型为
int
但应为int -> bool
类型的表达式int -> bool
我无法重现您报告的问题。 这是我尝试输入代码时看到的内容:
$ ocaml
OCaml version 4.02.1
# let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [] ;;
val filter : 'a -> ('b * 'a) list -> 'b list = <fun>
# filter 0 [(1,0); (2,1); (3,0)];;
- : int list = [1]
没有错误,但是得到了错误的答案。 这就是我期望查看您的代码的原因。
您得到的错误是说编译器在某个地方期望一个int -> bool
函数,但是您给它一个int
。 出现此错误的原因是因为您有一个等式( f = snd x
),其中f
的类型为snd x
int -> bool
而snd x
的类型为int
。 赋予相等性的两个参数必须具有相同的类型。 相反,您想要做的只是将f
应用于x
的第二个元素的结果,例如:
let rec filter f = function
| []->[]
| x::l -> if f (snd x) then fst x :: filter f l else [];;
也就是说,我建议您使用模式匹配而不是fst
和snd
,例如:
let rec filter f l =
match l with
| [] -> []
| (x,y)::l -> if f y then x :: filter f l else filter f l
请注意, fy
将返回bool类型的内容,然后它将确定采用哪个分支。
Matts的答案完全正确。 最好重用现有功能,而不是从头开始编写特殊代码:
[(1,0);(2,1);(3,0);(4,1)]
|> List.filter (fun (_, x) -> x = 0)
|> List.map fst
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.