我有一个功能:
let rec multiply x ls =
match ls with
[] -> []
| h::tl -> (x * h) :: multiply x tl
乘以2 [1; 2; 3] = [2; 4; 6]
我想要一个从n乘以0到0的函数。由于基本情况我一直遇到问题:
let rec multiply_all x ls = if x > 0
then (multiply n ls) :: multiply_all (n-1) (ls) else ????
我不确定在别人之后放什么。我试着做到了
if x > 1 then (multiply n ls) :: multiply_all (n-1) (ls) else multiply all 1.
但这不起作用。
答案 0 :(得分:1)
由于1
必须返回列表,因此放置multiply_all
肯定不起作用。所以你需要一个列表(int
列表)放在那里。但它应该是哪个列表?
简短的回答是,在这种简单的情况下,您需要的列表通常是空列表:[]
。
作为稍微长一点的答案,我们可以考虑与multiply_all 0
,multiply_all 1
等的预期结果相关的multiply_all 2
的情况,并尝试找到适合的模式。我们希望multiply_all
的行为如下:
# multiply_all 2 [1;2;3];;
- : int list list = [[2; 4; 6]; [1; 2; 3]]
# multiply_all 1 [1;2;3];;
- : int list list = [[1; 2; 3]]
因此,使用一些数字 N 作为第一个参数调用multiply_all
应该会给我们一个长度为 N 的列表。特别是, N = 0的multiply_all
应该给出一个长度为0的列表。长度为0的列表是空列表。
以下是您完成的定义:
let rec multiply_all x ls =
if x > 0 then (multiply x ls) :: multiply_all (x-1) (ls) else []
答案 1 :(得分:0)
只是另一个解决方案:
let multiply_all n l =
let multiply n= List.map (( * ) n) in
let rec aux i acc =
if i > n then acc
else aux (i+1) (multiply i l :: acc)
in
aux 1 []
;;
测试:
# multiply_all 5 [1;2;3];;
- : int list list =
[[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]]
答案 2 :(得分:-1)
首先,您的multiply
方法非常低效,因为它不是尾递归。此外,标准库为您提供了使这类函数更易于编写的工具:
let multiply n = List.map (( * ) n);;;
val multiply : int -> int list -> int list = <fun>
multiply 5 [1;2;3];;
- : int list = [5; 10; 15]
注意:另外,如果不对代码进行模糊处理,请使用部分应用程序。
截至multiply_all
,如果没有JaneStreet Core
,我不确定如何实现它(请参阅this question)。但是,这是使用Core
:
open Core.Std;; (*Using Core*)
let multiply_all n l =
let multiples = List.init n ~f:(fun x -> n-x) in (*This doesn't exist in Pervasives*)
List.map multiples ~f:(fun m -> multiply l m);;
val multiply_all : int list -> int -> int list list = <fun>
multiply_all 5 [1;2;3];;
- : int list list = [[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]]
希望它有所帮助。我会根据我对List.init
的调查结果更新此答案。