ReadFromSTDIN (2)
Written by: Hongwei Xi (the creator of ATS)
Intro
If you have not yet read ReadFromSTDIN, please do so first.
The code in this example does essentially the same as the code in ReadFromSTDIN, but it is written in a style that stresses the use of combinators in functional programming.
Prompts
The following function prompts
returns a linear stream of
integers:
fun
prompts
(
// argless
) : stream_vt(int) =
stream_vt_map<int><int>
(
sint_streamize_gte(0) // HX: generating 0, 1, 2, 3, ...
) where
{
impltmp
stream_vt_map$fopr<int><int>(i) =
(println!("Please input an integer or type Ctrl-D:"); i)
}
For each integer in the stream to be computed, a message (for the purpose of prompting the user) is printed onto the standard output (STDOUT).
Tally
The function tally
can be given the following combinator-based
implementation:
fun
tally() = let
val ps = prompts()
val xs =
FILEref_streamize_line(the_stdin())
val xs =
stream_vt_filter<string>(xs) where
{
impltmp
stream_vt_filter$test<string>(x0) = isneqz(x0)
}
val ys =
(
stream_vt_z2map<int,string><int>(ps, xs)
) where
{
impltmp
stream_vt_z2map$fopr<int,string><int>(p0, x0) = $extfcall(int, "atoi", x0)
}
in
stream_vt_foldleft0<int><int>(ys, 0) where
{
impltmp
stream_vt_foldleft0$fopr<int><int>(r0, y0) = r0 + y0
}
end // end of [tally]
The code for tally
is largely self-explanatory: ps
refers to a
stream for producing prompts and xs
to a stream of strings
representing non-empty lines read from STDIN; calling z2map
on ps
and xs
builds a stream ys
of int-values where each value is
converted from a string in xs
; calling foldleft0
on ys
returns
the sum of all of the int-values contained in ys
(while consuming
the linear stream ys
).
Happy programming in ATS!!!