datatype 'a stream =
Nil
| Cons of 'a * (unit -> 'a stream);
exception Bad of string;
fun from seed next = Cons (seed, fn () => from (next seed) next);
fun head (Nil) = raise Bad "got nil in head"
| head (Cons (h, t)) = h;
fun tail (Nil) = raise Bad "got nil in tail"
| tail (Cons (h, t)) = t ();
fun take 0 stream = []
| take n (Nil) = raise Bad "got nil in take"
| take n (Cons (h, t)) = h :: (take (n - 1) (t ()));
我尝试编写一个无限阶乘流,它需要两个流并输出一个流。
fun fac(a,b) = Cons(a, fn() => fac(b, a*(b-1));
这是我到目前为止所拥有的。但它没有给我正确的答案。
答案 0 :(得分:2)
我不认为使用因子流来获取任何输入是有意义的,因为因子形成了一个特定的序列。
相反,你需要一个帮助函数来管理内部状态( n 和 n !),然后流本身只是一个值:
local
(* returns a stream consisting of
nFac,
nFac * nextN,
nFac * nextN * (nextN + 1),
nFac * nextN * (nextN + 1) * (nextN + 2),
...
*)
fun facHelper (nFac, nextN) = Cons (nFac, fn () => facHelper (nFac * nextN, nextN + 1))
in
(* a stream consisting of 0!, 1!, 2!, 3!, ... *)
val factorials = facHelper (1, 1)
end
或者,您可以创建数字1,2,3,...和流减少器的流,给定流 s ,返回1的流, s 1 , s 1 s 2 , s 1 s 2 s 3 ,...:
local
(* returns a stream consisting of n, n + 1, n + 2, n + 3, ... *)
fun positiveIntegersHelper n = Cons (n, fn () => positiveIntegersHelper (n + 1))
in
(* a stream consisting of 1, 2, 3, 4, ... *)
val positiveIntegers = positiveIntegersHelper 1
end
(* Note: the above could also have been written using your 'from' function, as
val positiveIntegers = from 1 (fn n => n + 1)
*)
(* given a function f, an initial value seed, and a stream consisting of [s1, s2, s3, ...],
returns a stream consisting of
[seed, f(s1, seed), f(s2, f(s1, seed)), f(s3, f(s2, f(s1, seed))), ...]
-- so, somewhat analogous to List.foldl, except that it returns a stream of all partial
results, instead of just the final result.
*)
fun reduceStream _ seed Nil = Cons (seed, fn () => Nil)
| reduceStream f seed (Cons (h, tf)) =
Cons (seed, fn () => reduceStream f (f (h, seed)) (tf ()))
(* a stream consisting of 0!, 1!, 2!, 3!, ... *)
val factorials = reduceStream op* 1 positiveIntegers