如何对包含整数的列表中的每个元素应用一个算术运算?

问题描述 投票:0回答:1

我想找出如何编写一个函数,该函数将接受两个参数,即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]];;
matrix ocaml tail-recursion
1个回答
0
投票

您正在此处处理列表清单。因此,您需要List.map列表列表,还需要List.map每个单独的列表。

当您执行List.map (List.fold_left ( + ) 0)时,将部分应用到两个功能:对于List.fold_left,您将提供要应用的功能和初始元素,并留下一个仍带有列表的功能。对于List.map,给出了第一个参数(要应用的函数),最后得到的函数仍然会使用列表列表:因此,在这一点上,它仍然是未评估的函数。您无法使用它执行mod 2,因为您没有整数。

您在顶部定义的ab实际上没有使用,因为它们会被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应用于。

© www.soinside.com 2019 - 2024. All rights reserved.