做Stream的诀窍

时间:2014-10-27 22:32:56

标签: ocaml

我目前正在尝试完全理解。这个概念并不复杂。它就像一个列表,但尾部是thunk而不是具体的子列表。

我可以写这样的流:

type 'a stream_t = Nil | Cons of 'a * (unit -> 'a stream_t)

let hd = function
  | Nil -> failwith "hd"
  | Cons (v, _) -> v

let tl = function
  | Nil -> failwith "tl"
  | Cons (_, g) -> g()

let rec take n = function
  | Nil -> []
  | Cons (_, _)  when n = 0 -> []
  | Cons (hd, g) -> hd::take (n-1) (g())


let rec filter f = function
  | Nil -> Nil
  | Cons (hd, g) ->
    if f hd then Cons (hd, fun() -> filter f (g()))
    else filter f (g())

到目前为止一直很好,我可以写一个简单的流:

let rec from i = Cons (i, fun() -> from (i+1))

现在,如果我被要求做一个 primes 流,我觉得非常困难。我想使用筛选算法。不考虑流,我可以轻松地做到。但对于流,我无法做到。

我搜索了代码:

(* delete multiples of p from a stream *)
let sift p = filter (fun n -> n mod p <> 0)

(* sieve of Eratosthenes *)
let rec sieve = function
  | Nil -> Nil
  | Cons (p, g) -> 
    let next = sift p (g()) in
    Cons (p, fun () -> sieve next)

(* primes *)
let primes = sieve (from 2)

我几乎可以理解它正在发挥作用。但诀窍在哪里?

另外如何进行列表的排列流?

0 个答案:

没有答案