(* CSE341 Autumn 2005, Lecture 8 code examples *)
(* our own version of map *)
fun mymap (f,[]) = []
| mymap (f,x::xs) = f x :: mymap(f,xs)
(* define our own version of fold -- ML has builtin foldr and foldl *)
fun fold (f,acc,[]) = acc
| fold (f,acc,x::xs) = fold (f, f(acc,x), xs)
fun sum s = fold ((op +), 0, s)
fun product s = fold ((op * ), 1, s)
fun and_list s = fold ((fn (x,y) => x andalso y), true, s)
fun or_list s = fold ((fn (x,y) => x orelse y), false, s)
(* interesting definition of member - not so practical
in ML though - works better in Miranda or Haskell *)
fun member (x,list) = or_list (mymap ((fn y => x=y), list))
(* 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);
(* In f1, 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 of 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);