47 lines
1.4 KiB
Plaintext
47 lines
1.4 KiB
Plaintext
(*
|
|
The task:
|
|
|
|
Create a function, compose, whose two arguments f and g, are
|
|
both functions with one argument.
|
|
|
|
The result of compose is to be a function of one argument,
|
|
(let's call the argument x), which works like applying function
|
|
f to the result of applying function g to x.
|
|
|
|
In ATS, we have to choose whether to use non-linear closures
|
|
(cloref) or linear closures (cloptr). In the latter case, we also
|
|
have to choose between closures allocated with malloc (or similar)
|
|
and closures allocated on the stack.
|
|
|
|
For simplicity, we will use non-linear closures and assume there is
|
|
a garbage collector, or that the memory allocated for the closures
|
|
can be allowed to leak. (This is often the case in a program that
|
|
does not run continuously.)
|
|
*)
|
|
|
|
#include "share/atspre_staload.hats"
|
|
|
|
(* The following is actually a *template function*, rather than a
|
|
function proper. It is expanded during template processing. *)
|
|
|
|
fn {t1, t2, t3 : t@ype}
|
|
compose (f : t2 -<cloref1> t3,
|
|
g : t1 -<cloref1> t2) : t1 -<cloref1> t3 =
|
|
lam x => f (g (x))
|
|
|
|
|
|
implement
|
|
main0 () =
|
|
let
|
|
val one_hundred = 100.0
|
|
val char_zero = '0'
|
|
val f = (lam y =<cloref1> add_double_int (one_hundred, y))
|
|
val g = (lam x =<cloref1> char2i x - char2i char_zero)
|
|
val z = compose (f, g) ('5')
|
|
val fg = compose (f, g)
|
|
val w = fg ('7')
|
|
in
|
|
println! (z : double);
|
|
println! (w : double)
|
|
end
|