如何使用其中一个折叠函数生成从0到n-1的整数列表?我对如何让fold_right返回一个列表而不仅仅返回一个累积值感到困惑。
这是一个帮助函数,我试图定义它来解决一个更大的问题。这是我的尝试:
- 我知道基本情况必须是一个只包含零的列表,因为我不想添加小于零的任何内容。
- 我知道我需要递减值n,这样我就可以将n-1中的数字放到列表中。
let buildList n =
let ibuildList elem list =
list@[n-1]
in List.fold_right ibuildList n [0];;
但是我得到了一个错误,强调了#34; n"在最后一行中说表达式是int类型但是表达式需要类型'列表。我不是通过[n-1]变成列表的整数吗?我哪里出错了?
答案 0 :(得分:2)
非常抱歉,我错过了至少一步的推理。
折叠用于遍历集合。既然你想要生成一个列表而你只有n
而不是一个集合,那么你就无法以任何合理的方式使用fold。事实上,你想要做的更像是展开。即,您想将n
展开到列表中。
编写此函数很容易,但使用折叠编写它并不容易。
这是OCaml中展开的实现:
let rec unfold_right f init =
match f init with
| None -> []
| Some (x, next) -> x :: unfold_right f next
以下是如何使用unfold_right
生成整数列表:
let range n =
let irange x = if x > n then None else Some (x, x + 1) in
unfold_right irange 1
以下是您运行range
时的外观:
# range 0;;
- : int list = []
# range 8;;
- : int list = [1; 2; 3; 4; 5; 6; 7; 8]
# range 5;;
- : int list = [1; 2; 3; 4; 5]
答案 1 :(得分:1)
替代版本,使用标准Stream模块:
[< 'n; nats_from (n + 1) >]
作品n
代表 lazy 列表,其中Stream.npeek n stream
为其头部,下一个自然数字为尾部。 n
使用stream
的第一个utop # #load "dynlink.cma";; (* you need these to work with *)
utop # #load "camlp4o.cma";; (* the Stream's syntactic extension *)
utop # range 1;;
- : int list = [0]
utop # range 5;;
- : int list = [0; 1; 2; 3; 4]
utop # range 10;;
- : int list = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9]
元素并将其作为列表返回。
使用utop进行测试:
$ ocamlc -pp camlp4o <filename>.ml
如果您想编译它,请使用以下命令(您需要使用camplp4o预处理器):
$ ocamlopt -pp camlp4o <filename>.ml
或
foos = new Foo[10];