[MLton-user] Stream Fusion
Stephen Weeks
sweeks at sweeks.com
Mon May 7 19:07:11 PDT 2007
Another standard way to hide existentials is to use a ref cell hidden
in a closure. I tried that for fusion and MLton, quite
pleasantly, generates identical code as for the exn approach.
loop_25:
fldL (0+((8*1)+(0*1)))(%ebp)
fcomp %st(1)
fnstsw %ax
testw $0x500,%ax
jnz L_2428
L_1114:
fld %st
faddL (globalReal64+((0*8)+(0*1)))
fxch %st(1)
fsqrt
faddp %st, %st(2)
jmp loop_25
SML code follows.
----------------------------------------------------------------------
datatype 'a step =
DONE
| GIVE of 'a
| SKIP
datatype 'a t = T of unit -> 'a step
val unfold : 's * ('s -> ('a * 's) option) -> 'a t =
fn (s, f) => let
val r = ref s
in T (fn () =>
case f (!r) of
NONE => DONE
| SOME (a, s) => (r := s; GIVE a))
end
val map : 'a t * ('a -> 'b) -> 'b t =
fn (T g, f) =>
T (fn () =>
case g () of
DONE => DONE
| SKIP => SKIP
| GIVE a => GIVE (f a))
val fold : 'a t * 'b * ('a * 'b -> 'b) -> 'b =
fn (T g, b, f) => let
fun loop b =
case g () of
DONE => b
| GIVE a => loop (f (a, b))
| SKIP => loop b
in
loop b
end
val n = valOf (Real.fromString (hd (CommandLine.arguments ())))
fun pr r = print (Real.toString r ^ "\n")
val sum =
fold (map
(unfold (1.0, fn i => if i <= n then SOME (i, i+1.0) else NONE),
Math.sqrt),
0.0,
op +)
val () = pr sum
More information about the MLton-user
mailing list