(* 'eg.sml' some standard functions often used in functional programming *) (* NB. They may differ slightly from those in the 'List' structure. *) fun hd (h::_) = h; fun tl (_::t) = t; fun null [] = true | null _ = false; fun range lo hi = let fun r lo = if lo > hi then [] else lo::r (lo+1) in r lo end; fun length [] = 0 | length (_::xs) = 1 + length xs; fun append [] ys = ys (* or infix @ *) | append (x::xs) ys = x::append xs ys; fun take _ [] = [] | take n (x::xs) = if n > 0 then x::take (n-1) xs else []; fun drop _ [] = [] | drop n (xxs as (_::xs)) = if n > 0 then drop (n-1) xs else xxs; fun map _ [] = [] | map f (x::xs) = (f x)::(map f xs); fun transpose ([]::_) = [] | transpose m = map hd m::transpose(map tl m); fun catOption [] = [] | catOption ((SOME x)::xs) = x::catOption xs | catOption ( NONE ::xs) = catOption xs; fun filter p [] = [] | filter p (x::xs) = if p x then x::filter p xs else filter p xs; fun foldl f z [] = z | foldl f z (x::xs) = foldl f (f z x) xs; fun foldr f z [] = z | foldr f z (x::xs) = f x (foldr f z xs); fun zip (x::xs) (y::ys) = (x,y)::(zip xs ys) | zip _ _ = []; fun unzip [] = ([], []) | unzip ((x,y)::xys) = let val (xs,ys) = unzip xys in (x::xs,y::ys) end; fun zipWith f (x::xs) (y::ys) = (f x y)::(zipWith f xs ys) | zipWith _ _ _ = []; fun twice f = f o f; fun curry f x y = f(x,y); fun uncurry f(x,y) = f x y; fun flip f x y = f y x; (* -----cse3322--L.A.--CSSE--Monash--U.--.au--7/2005-- *) val l = range 1 6; (* tests *) val m = [[1,2,3],[4,5,6],[7,8,9]]; length l; append l l; take 2 l; drop 2 l; map ord (explode "abcd"); transpose m; filter (fn n => n div 2 * 2 = n) l; foldl (curry(op -)) 0 l; foldr (curry(op -)) 0 l; zip l l; unzip [(1,2),(3,4)]; zipWith (curry(op +)) l l; twice (drop 1) l; flip (curry (op -)) 3 4; (* --------------------------------------------------- *)