List 使用高阶函数的OCaml错误过滤器列表
所以我有这个练习:List 使用高阶函数的OCaml错误过滤器列表,list,function,types,filter,ocaml,List,Function,Types,Filter,Ocaml,所以我有这个练习: 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 [
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
我无法重现你报告的问题。以下是我在尝试您的代码时看到的内容:
$ 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]
$ocaml
OCaml版本4.02.1
#let rec filter f=函数
| []->[]
|x::l->如果f=snd x,则fst x::filter f l else[];;
val筛选器:'a->('b*'a)列表->'b列表=
#过滤器0[(1,0);(2,1);(3,0)];;
-:int list=[1]
没有错误,但它得到了错误的答案。这就是我在查看您的代码时所期望的。我无法重现您报告的问题。以下是我在尝试您的代码时看到的内容:
$ 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]
$ocaml
OCaml版本4.02.1
#let rec filter f=函数
| []->[]
|x::l->如果f=snd x,则fst x::filter f l else[];;
val筛选器:'a->('b*'a)列表->'b列表=
#过滤器0[(1,0);(2,1);(3,0)];;
-:int list=[1]
没有错误,但它得到了错误的答案。这就是我在查看您的代码时所期望的。您得到的错误是,编译器在某个地方需要一个
int->bool
函数,但您给了它一个int
。出现此错误的原因是因为有一个等式(f=snd x
),其中f
的类型为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 [];;
let rec filter f l =
match l with
| [] -> []
| (x,y)::l -> if f y then x :: filter f l else filter f l
也就是说,我建议使用模式匹配而不是fst
和snd
,例如:
let rec filter f = function
| []->[]
| x::l -> if f (snd x) then fst x :: filter f l else [];;
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类型的内容,然后确定采用哪个分支。您得到的错误是,编译器在某个地方需要一个int->bool
函数,但您给了它一个int
。出现此错误的原因是因为有一个等式(f=snd x
),其中f
的类型为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 [];;
let rec filter f l =
match l with
| [] -> []
| (x,y)::l -> if f y then x :: filter f l else filter f l
也就是说,我建议使用模式匹配而不是fst
和snd
,例如:
let rec filter f = function
| []->[]
| x::l -> if f (snd x) then fst x :: filter f l else [];;
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
尽管马特斯的答案是正确的。最好是重用现有函数,而不是从头开始编写特殊函数:
[(1,0);(2,1);(3,0);(4,1)]
|> List.filter (fun (_, x) -> x = 0)
|> List.map fst
是的,你是对的,我忘了加上f必须像我的例子,而不仅仅是一个数字。你可以有“(funx->x!=0)”或“(funx->x>3)”或任何类似的,谢谢!好的,如果f=snd x,那么
就没有意义了。这将f(作为值)与该对的第二个元素进行比较。您希望将f作为函数调用。如果f(snd x)
,这看起来更像。是的,你是对的,我忘了加上f必须像我的例子,而不仅仅是一个数字。你可以有“(fun x->x!=0)”或“(fun x->x>3)”或类似的东西,谢谢!好的,如果f=snd x,那么就没有意义了。这将f(作为值)与该对的第二个元素进行比较。您希望将f作为函数调用。如果f(sndx)
,这看起来更像。