析因流SML

时间:2017-02-15 01:06:15

标签: sml

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));

这是我到目前为止所拥有的。但它没有给我正确的答案。

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