我想找出如何编写一个函数,该函数将接受两个参数,即a'和b'(即函数),以及列表列表;
然后,如果int-lists列表中任何列表中的元素之和(我指的是整数)是一个奇数,它将执行乘法运算-函数a'(使用相同的整数-> x * x乘以该列表中的每个元素)。
否则,如果int-lists列表中任何列表中的元素之和为偶数,它将执行加法运算-函数b'(添加相同的整数-> x + x),然后将该列表中的每个元素覆盖。
因此,带有输入的函数调用如下:
func a b [[1;3];[8;3]];;
...,然后输出应如下所示:
- : int list list = [[2; 6]; [64; 9]]
第一个列表中元素的总和为偶数,因此将第一个列表相加并且第二个列表中的元素之和为奇数,这意味着第二个列表将相乘。
我已经在Ocaml中将此功能作为练习编写了,我真的很难理解这种语言;我想知道我在做什么错...此外,战略帮助将不胜感激! -就是对事物的解释确实可以在Ocaml中工作,尽管我并不是Ocaml的完全新手,但我已经学到了很多有关尾递归函数的知识,只是函数之间的参数交换困扰着我。
确定,这是代码:
let a = List.map (List.fold_left ( + ) 0)
let b = List.map (List.fold_left ( * ) 0)
let rec func a b lists = if lists = [] then []
else if ((List.map (List.fold_left ( + ) 0)) mod 2 = 0) then List.map
(List.fold_left ( + ) 0)
else List.map (List.fold_left ( * ) 0)
(* Function call: *)
func (fun x -> x*x) (fun x -> x+x) [[1;3];[5;7]];;
您正在此处处理列表清单。因此,您需要List.map
列表列表,还需要List.map
每个单独的列表。
当您执行List.map (List.fold_left ( + ) 0)
时,将部分应用到两个功能:对于List.fold_left
,您将提供要应用的功能和初始元素,并留下一个仍带有列表的功能。对于List.map
,给出了第一个参数(要应用的函数),最后得到的函数仍然会使用列表列表:因此,在这一点上,它仍然是未评估的函数。您无法使用它执行mod 2
,因为您没有整数。
您在顶部定义的a
和b
实际上没有使用,因为它们会被func
中的函数参数遮盖。当您呼叫func (fun x -> x*x) (fun x -> x+x) [[1;3];[5;7]];;
时,a
将为(fun x -> x*x)
,b
将为(fun x -> x+x)
,而您的lists
将为[[1;3];[5;7]]
。
您的func
不是递归函数。您使用的List.map
不是尾递归,而List.fold_left
是。看到:https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALmaphttps://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALfold_left这可能有助于理解尾递归:https://www.cs.cornell.edu/courses/cs3110/2020sp/textbook/data/tail_recursion.html
我会最少将您的代码更改为此:
let func a b lists =
let is_even l = List.fold_left ( + ) 0 l mod 2 = 0 in
List.map (fun l -> if is_even l then List.map b l else List.map a l) lists
(* Function call: *)
let _ = func (fun x -> x*x) (fun x -> x+x) [[1;4];[5;7]]
它映射列表的列表,所以l
是一个列表。然后,它检查该列表的总和是否为偶数,如果是,则对每个单独的元素应用函数b
,否则将函数a
应用于。