2009-10-27 143 views
8

如何制作一个懒惰列表来表示一个双倍数字序列?例如:Ocaml:懒惰列表

1 2 4 8 16 32 
+1

你是指懒惰列表的一些特定实现,或者只是一般概念?另外,你是否真的需要懒惰_lists_(其中的值,一旦计算出来,被记住),或者你真的只想要一个流(其中值不记忆,因此只能被读取一次)? – 2009-10-27 16:43:52

+0

我在找流。 – 2009-10-27 16:44:34

回答

9

伟大的博客解放的头脑,对这个话题有很大的文章:

http://enfranchisedmind.com/blog/posts/ocaml-lazy-lists-an-introduction/

您还可以检查出http://batteries.forge.ocamlcore.org/doc.preview%3Abatteries-beta1/html/api/Lazy%5Flist.html

这是标准库处理这一。

这个问题也很类似于这样的问题:

What OCaml libraries are there for lazy list handling?

+0

第一个链接不再工作,他们移动主机? – Oleg 2017-03-06 19:23:40

+0

@Oleg看起来像域名过期。这就是互联网上的生活。这个答案现在差不多8岁了:) – chollida 2017-03-07 21:55:39

+0

电池库现在有[三种不同的或多或少的惰性序列类型](https://github.com/ocaml-batteries-team/batteries-included/wiki/ListTypes),具有不同的属性。 – Mars 2018-01-20 18:11:31

13

使用流:

let f x = Stream.from (fun n -> Some (x * int_of_float (2.0 ** float_of_int n))) 

let f x = 
    let next = ref x in 
    Stream.from (fun _ -> let y = !next in next := 2 * y ; Some y) 

使用自定义lazy_list类型:

type 'a lazy_list = 
    | Nil 
    | Cons of 'a * 'a lazy_list lazy_t 
let rec f x = lazy (Cons (x, f (2*x))) 
1

如果你想通过做手工,我说你必须主要选项:

  • 使用自定义lazy_list型,如ephemient说(除了他的解决方案是一个有点坏) :

    type 'a lazy_list = 
        | Nil 
        | Cons of 'a * 'a lazy_list 
    
    let head = function 
        | Nil -> failwith "Cannot extract head of empty list" 
        | Cons (h, _) -> h 
    
    let tail = function 
        | Nil -> failwith "Cannot extract tail of empty list" 
        | Cons (_, t) -> t 
    
  • 用一种thunk的(如用于实现在不支持此功能的语言懒评价的东西)。你可以将你的列表定义为函数unit -> 'a,该函数说明如何从当前元素获取下一个元素(不需要为此使用流)。例如,定义所有自然数的列表,如果你做

    print_int (naturals()); 
    print_int (naturals()); 
    print_int (naturals()) 
    

    ,你会得到下面的输出,你可以做

    let make_lazy_list initial next = 
        let lazy_list current() = 
         let result = !current in 
         current := (next !current); result 
        in lazy_list (ref initial) 
    
    let naturals = make_lazy_list 0 (function i -> i + 1) 
    

    的:

    0 
    1 
    2 
    
+0

我的'lazy_list'的哪部分被破坏?我在写代码时没有对它进行测试,而且我确实比OCaml更熟悉Haskell和SML,但我刚刚测试了它,它在OCaml 3.11.1上运行。数据流主要是因为OP在询问数据流的问题上添加了一条评论。 – ephemient 2009-10-27 19:05:33

+0

Woops,你是对的,我真的*误会了......另外我没有看到关于使用流的评论。下次我会把眼镜放在:s。 – jdb 2009-10-27 21:54:36

3

此外,在我的OCaml Network Application Environment核心基金会中有一个名为Cf_seq的懒惰列表模块。实际上,我写了一整套函数式数据结构。它全部在2分条款的BSD许可下提供。请享用。

更新:代码已被重命名为“Oni”,它现在托管在BitBucket。您也可以使用GODI软件包。