# 将ocaml函数转换为流converting ocaml function to stream

``````let genblocks () =
let blocks = ref [] in
let rec loop depth block =
let iter i = loop (depth - 1) (i :: block) in
match depth with
| 0 -> blocks := block :: !blocks
| _ -> List.iter iter [1;2;3;4]
in
loop 4 [];
!blocks
``````

## 3 个回复3

### ===============>>#1 票数：3 已采纳

1. 演示通用技术来摆脱你的可变变量

2. 一种特定于算法的技术，可以很容易地生成流

3. 指向将任何生产者转变为按需流的通用技术的链接

``````let genblocks n =
(* base = [1; ... ; n] *)
let base = Array.to_list (Array.init n (fun i -> i+1)) in
let blocks = ref [] in
let rec loop depth block =
let iter i = loop (depth - 1) (i :: block) in
match depth with
| 0 -> blocks := block :: !blocks
| _ -> List.iter iter base
in
loop n [];
!blocks
``````

``````let genblocks n =
let base = Array.to_list (Array.init n (fun i -> i+1)) in
let rec loop depth blocks block =
let iter blocks i = loop (depth - 1) blocks (i :: block) in
match depth with
| 0 -> block :: blocks
| _ -> List.fold_left iter blocks base
in
loop n [] []
``````

``````# genblocks 3;;
- : int list list =
[[3; 3; 3]; [2; 3; 3]; [1; 3; 3]; [3; 2; 3]; [2; 2; 3]; [1; 2; 3]; [3; 1; 3];
[2; 1; 3]; [1; 1; 3]; [3; 3; 2]; [2; 3; 2]; [1; 3; 2]; [3; 2; 2]; [2; 2; 2];
[1; 2; 2]; [3; 1; 2]; [2; 1; 2]; [1; 1; 2]; [3; 3; 1]; [2; 3; 1]; [1; 3; 1];
[3; 2; 1]; [2; 2; 1]; [1; 2; 1]; [3; 1; 1]; [2; 1; 1]; [1; 1; 1]]
``````

``````let decr n block =
let rec decr n = function
| [] -> raise Exit
| 1::rest -> n :: decr n rest
| i::rest -> (i - 1) :: rest
in try Some (decr n block) with Exit -> None
``````

``````decr 3 [3;3;3];;
- : int list option = Some [2; 3; 3]
# decr 3 [1;2;3];;
- : int list option = Some [3; 1; 3]
# decr 3 [1;1;1];;
- : int list option = None
``````

``````let start n = Array.to_list (Array.make n n)

let genblocks n =
let rec gen = function
| None -> []
| Some curr -> curr :: gen (decr n curr)
in gen (Some (start n))
``````

``````let genblocks n =
let curr = ref (Some (start n)) in
Stream.from (fun _ ->
match !curr with
| None -> None
| Some block ->
curr := (decr n block);
Some block
)

# Stream.npeek 100 (genblocks 3);;
- : int list list =
[[3; 3; 3]; [2; 3; 3]; [1; 3; 3]; [3; 2; 3]; [2; 2; 3]; [1; 2; 3]; [3; 1; 3];
[2; 1; 3]; [1; 1; 3]; [3; 3; 2]; [2; 3; 2]; [1; 3; 2]; [3; 2; 2]; [2; 2; 2];
[1; 2; 2]; [3; 1; 2]; [2; 1; 2]; [1; 1; 2]; [3; 3; 1]; [2; 3; 1]; [1; 3; 1];
[3; 2; 1]; [2; 2; 1]; [1; 2; 1]; [3; 1; 1]; [2; 1; 1]; [1; 1; 1]]
``````

### ===============>>#3 票数：0

``````open IterExtra (* add some handy symbols to manipulate iterators *)
let genblock n = (Iter.range 1 (4+1)) \$^ n
val genblock : int -> int list Iter.iter
``````

``````let genblock n = (Iter.range 1 (4+1)) \$^ n |> Iter.filter prune
val genblock : int -> int list Iter.iter
``````

``````let n = 10;;
Iter.iter print (genblock n);;
``````