(* lec09.sml *)
(* curried version of filter *)
fun filter f [] = []
| filter f (x::xs) = if f x
then x :: filter f xs
else filter f xs
fun even j = j mod 2 = 0;
val evens = filter even;
val x1 = [1,2,3,4,5,6,13];
val x2 = evens x1;
(* curried version of member - test whether something is a member of a list *)
fun member x [] = false
| member x (y::ys) = if x = y then true else member x ys
(* sort of silly function to test whether a list contains 13 *)
val unlucky = member 13;
val x3 = map unlucky [x1,x2];
(* A fold function *)
fun myfoldl f acc nil = acc
| myfoldl f acc (x::xs) = myfoldl f (f(x,acc)) xs;
fun sum s = myfoldl (op +) 0 s;
fun product s = myfoldl (op * ) 1 s;
fun and_list s = myfoldl (fn (x,y) => x andalso y) true s;
fun or_list s = myfoldl (fn (x,y) => x orelse y) false s;
val x4 = sum x2;
val x5 = product x2;
val x6 = and_list (map even x2);
(* interesting definition of member - not so practical
in ML though *)
fun member x l = or_list (map (fn y => x = y) l);
val x7 = member 13 x1;
(* combining functions *)
(* in f1, we just apply h to the argument, then g to the result *)
fun f1 (g,h) = fn x => g (h x);
val x8 = f1(Math.sqrt,(fn x => x*x));
val x9 = x8 42.0;
(* In f2, we apply g to the argument. This returns an option type. If
the result is none, we apply h to the argument instead and return
that. Otherwise if the result is something, we return that something. *)
fun f2 (g,h) = fn x =>
case g x of NONE => h x | SOME y => y;
(* return the sqrt of a number if it's non-negative, otherwise
NONE if it's negative *)
fun sqrt_or_none x = if x>=0.0 then SOME (Math.sqrt(x)) else NONE;
(* define a function that takes the sqrt of a non-negative number, or
the exp of the number if it's negative *)
val weird = f2(sqrt_or_none, Math.exp);
val weirdans = map weird [~2.0, ~1.0, 0.0, 1.0, 2.0];