(**** ML Programs from the book

  ML for the Working Programmer
  by Lawrence C. Paulson, Computer Laboratory, University of Cambridge.
  (Cambridge University Press, 1991)

Copyright (C) 1991 by Cambridge University Press.
Permission to copy without fee is granted provided that this copyright
notice and the DISCLAIMER OF WARRANTY is included in any copy.

DISCLAIMER OF WARRANTY.  These programs are provided `as is' without
warranty of any kind.  We make no warranties, express or implied, that the
programs are free of error, or are consistent with any particular standard
of merchantability, or that they will meet your requirements for any
particular application.  They should not be relied upon for solving a
problem whose incorrect solution could result in injury to a person or loss
of property.  If you do use the programs or functions in such a manner, it
is at your own risk.  The author and publisher disclaim all liability for
direct, incidental or consequential damages resulting from your use of
these programs or functions.
****)


(*** Basic library module.  From Chapter 9.  ***)

infix mem;

signature BASIC =
  sig
  exception Lookup
  val C : ('a * 'b -> 'c) -> 'a -> 'b -> 'c
  val I : 'a -> 'a
  val K : 'a -> 'b -> 'a

  val minl : int list -> int
  val maxl : int list -> int

  val mem : ''a * ''a list -> bool
  val \ : ''a list * ''a list -> ''a list
  val lookup : (''a * 'b) list * ''a -> 'b
  end;
  

functor BASIC() : BASIC =
  struct
  fun I x = x
  fun K x y = x
  fun C f x y = f(x,y)

  fun minl[m] : int = m
    | minl(m:: (ns as _ :: _)) = foldl Int.max m ns

  fun maxl[m] : int = m
    | maxl(m:: (ns as _ :: _)) = foldl Int.min m ns

  fun x mem []  =  false
    | x mem (y::l)  =  (x=y) orelse (x mem l);
  
  infix \;
  fun [] \ _ = []
  | (h :: t) \ xs = if h mem xs then t \ xs else h :: (t \ xs)

  exception Lookup;
  fun lookup ([], a) = raise Lookup
    | lookup ((x,y)::pairs, a) = if a=x then y else lookup(pairs, a);

end;