首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在OCaml中生成递归列表

如何在OCaml中生成递归列表
EN

Stack Overflow用户
提问于 2013-10-18 19:16:12
回答 4查看 1.4K关注 0票数 3

我想实现Haskell cycle函数的模拟。

如果我显式地传递list元素,这似乎是微不足道的:

代码语言:javascript
运行
复制
let cycle a b c =
  let rec l = a::b::c::l in
  l

cycle 1 2 3生成递归列表1, 2, 3, 1...

但是,如何在另一个常规列表的基础上生成递归列表?

代码语言:javascript
运行
复制
let cycle lst = ...

用法

cycle [1;2;3]

EN

回答 4

Stack Overflow用户

发布于 2013-10-18 20:02:56

在像ML这样的热切的语言中,您需要使用流。例如

代码语言:javascript
运行
复制
# let cycle = Stream.from (fun n -> Some (List.nth [1;2;3] (n mod 3)));;
val cycle : int Stream.t = <abstr>
# Stream.npeek 10 cycle;;
- : int list = [1; 2; 3; 1; 2; 3; 1; 2; 3; 1]
票数 3
EN

Stack Overflow用户

发布于 2013-10-18 19:48:41

据我所见,OCaml不适合这种编码,除非您想深入到语言的不安全部分。

坚持语言的安全部分(但使用来自第7章的扩展),这里有一个(不太令人印象深刻的) cycle版本,它适用于长度为3的列表:

代码语言:javascript
运行
复制
let cycle = function
    | [] -> []
    | [x] -> let rec res = x :: res in res
    | [x; y] -> let rec res = x :: q and q = y :: res in res
    | [x; y; z] -> let rec res = x :: t and t = y :: v and v = z :: res in res
    | _ -> failwith "list too long"

很容易看出如何将其扩展到任何所需的固定长度,而不是任意长度。

下面是一个函数的会话:

代码语言:javascript
运行
复制
# #use "cyc.ml";;
val cycle : 'a list -> 'a list = <fun>
# cycle [1;2;3];;
- : int list =
[1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1;
 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2;
 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3;
 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1;
 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2;
 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; 3; 1; 2; ...]

无论如何,这是我能做的最好的了。希望能帮上忙。

票数 1
EN

Stack Overflow用户

发布于 2013-10-18 21:02:48

您也可以这样定义它。

代码语言:javascript
运行
复制
# let cycle items =
    let buf = ref [] in
    let rec next i =
      if !buf = [] then buf := items;
      match !buf with
        | h :: t -> (buf := t; Some h)
        | [] -> None in
    Stream.from next;;
val cycle : 'a list -> 'a Stream.t = <fun>

utop # let test = cycle [1; 2; 3];;
val test : int Stream.t = <abstr> 
utop # Stream.npeek 10 test;;
- : int list = [1; 2; 3; 1; 2; 3; 1; 2; 3; 1]

这是因为:

http://ocaml.org/tutorials/streams.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19457414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档