繁体   English   中英

使用高阶函数的OCaml错误过滤器列表

[英]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 -> boolsnd x的类型为int 赋予相等性的两个参数必须具有相同的类型。 相反,您想要做的只是将f应用于x的第二个元素的结果,例如:

let rec filter f = function
  | []->[]
  | x::l -> if f (snd x) then fst x :: filter f l else [];;

也就是说,我建议您使用模式匹配而不是fstsnd ,例如:

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM