src/Pure/library.ML
changeset 255 ee132db91681
parent 245 faf3de36fdb1
child 265 443dc2c37583
equal deleted inserted replaced
254:b1fcd27fcac4 255:ee132db91681
    42 
    42 
    43 exception OPTION of string;
    43 exception OPTION of string;
    44 
    44 
    45 fun the (Some x) = x
    45 fun the (Some x) = x
    46   | the None = raise OPTION "the";
    46   | the None = raise OPTION "the";
       
    47 
       
    48 fun if_none None y = y
       
    49   | if_none (Some x) _ = x;
    47 
    50 
    48 fun is_some (Some _) = true
    51 fun is_some (Some _) = true
    49   | is_some None = false;
    52   | is_some None = false;
    50 
    53 
    51 fun is_none (Some _) = false
    54 fun is_none (Some _) = false
   254 (*inverse of ~~; the old 'split':
   257 (*inverse of ~~; the old 'split':
   255   [(x1, y1), ..., (xn, yn)]  ===>  ([x1, ..., xn], [y1, ..., yn])*)
   258   [(x1, y1), ..., (xn, yn)]  ===>  ([x1, ..., xn], [y1, ..., yn])*)
   256 fun split_list (l: ('a * 'b) list) = (map #1 l, map #2 l);
   259 fun split_list (l: ('a * 'b) list) = (map #1 l, map #2 l);
   257 
   260 
   258 
   261 
   259 
       
   260 (* prefixes, suffixes *)
   262 (* prefixes, suffixes *)
   261 
   263 
   262 infix prefix;
   264 infix prefix;
   263 fun [] prefix _ = true
   265 fun [] prefix _ = true
   264   | (x :: xs) prefix (y :: ys) = x = y andalso (xs prefix ys)
   266   | (x :: xs) prefix (y :: ys) = x = y andalso (xs prefix ys)
   266 
   268 
   267 (* [x1, ..., xi, ..., xn]  --->  ([x1, ..., x(i-1)], [xi, ..., xn])
   269 (* [x1, ..., xi, ..., xn]  --->  ([x1, ..., x(i-1)], [xi, ..., xn])
   268    where xi is the first element that does not satisfy the predicate*)
   270    where xi is the first element that does not satisfy the predicate*)
   269 fun take_prefix (pred : 'a -> bool)  (xs: 'a list) : 'a list * 'a list =
   271 fun take_prefix (pred : 'a -> bool)  (xs: 'a list) : 'a list * 'a list =
   270   let fun take (rxs, []) = (rev rxs, [])
   272   let fun take (rxs, []) = (rev rxs, [])
   271         | take (rxs, x::xs) =
   273         | take (rxs, x :: xs) =
   272             if  pred x  then  take(x::rxs, xs)  else  (rev rxs, x::xs)
   274             if  pred x  then  take(x :: rxs, xs)  else  (rev rxs, x :: xs)
   273   in  take([], xs)  end;
   275   in  take([], xs)  end;
   274 
   276 
   275 (* [x1, ..., xi, ..., xn]  --->  ([x1, ..., xi], [x(i+1), ..., xn])
   277 (* [x1, ..., xi, ..., xn]  --->  ([x1, ..., xi], [x(i+1), ..., xn])
   276    where xi is the last element that does not satisfy the predicate*)
   278    where xi is the last element that does not satisfy the predicate*)
   277 fun take_suffix _ [] = ([], [])
   279 fun take_suffix _ [] = ([], [])
   372         chr (ord ch - ord "A" + ord "a")
   374         chr (ord ch - ord "A" + ord "a")
   373       else ch;
   375       else ch;
   374   in implode o (map lower) o explode end;
   376   in implode o (map lower) o explode end;
   375 
   377 
   376 
   378 
       
   379 (*parentesize*)
       
   380 fun parents lpar rpar str = lpar ^ str ^ rpar;
       
   381 
   377 (*simple quoting (does not escape special chars)*)
   382 (*simple quoting (does not escape special chars)*)
   378 fun quote s = "\"" ^ s ^ "\"";
   383 val quote = parents "\"" "\"";
   379 
   384 
   380 (*space_implode "..." (explode "hello"); gives "h...e...l...l...o"*)
   385 (*space_implode "..." (explode "hello"); gives "h...e...l...l...o"*)
   381 fun space_implode a bs = implode (separate a bs);
   386 fun space_implode a bs = implode (separate a bs);
   382 
   387 
       
   388 val commas = space_implode ", ";
       
   389 
   383 (*concatenate messages, one per line, into a string*)
   390 (*concatenate messages, one per line, into a string*)
   384 val cat_lines = implode o (map (apr (op ^, "\n")));
   391 val cat_lines = space_implode "\n";
   385 
   392 
   386 
   393 
   387 
   394 
   388 (** lists as sets **)
   395 (** lists as sets **)
   389 
   396 
   466 (*returns the tail beginning with the first repeated element, or []*)
   473 (*returns the tail beginning with the first repeated element, or []*)
   467 fun findrep [] = []
   474 fun findrep [] = []
   468   | findrep (x :: xs) = if x mem xs then x :: xs else findrep xs;
   475   | findrep (x :: xs) = if x mem xs then x :: xs else findrep xs;
   469 
   476 
   470 
   477 
       
   478 (*returns a list containing all repeated elements exactly once; preserves
       
   479   order, takes first of equal elements*)
       
   480 fun gen_duplicates eq lst =
       
   481   let
       
   482     val memb = gen_mem eq;
       
   483 
       
   484     fun dups (rev_dups, []) = rev rev_dups
       
   485       | dups (rev_dups, x :: xs) =
       
   486           if memb (x, rev_dups) orelse not (memb (x, xs)) then
       
   487             dups (rev_dups, xs)
       
   488           else dups (x :: rev_dups, xs);
       
   489   in
       
   490     dups ([], lst)
       
   491   end;
       
   492 
       
   493 val duplicates = gen_duplicates (op =);
       
   494 
       
   495 
   471 
   496 
   472 (** association lists **)
   497 (** association lists **)
   473 
   498 
   474 (*association list lookup*)
   499 (*association list lookup*)
   475 fun assoc ([], key) = None
   500 fun assoc ([], key) = None
   478 
   503 
   479 fun assocs ps x =
   504 fun assocs ps x =
   480   (case assoc (ps, x) of
   505   (case assoc (ps, x) of
   481     None => []
   506     None => []
   482   | Some ys => ys);
   507   | Some ys => ys);
       
   508 
       
   509 (*two-fold association list lookup*)
       
   510 fun assoc2 (aal, (key1, key2)) =
       
   511   (case assoc (aal, key1) of
       
   512     Some al => assoc (al, key2)
       
   513   | None => None);
   483 
   514 
   484 (*generalized association list lookup*)
   515 (*generalized association list lookup*)
   485 fun gen_assoc eq ([], key) = None
   516 fun gen_assoc eq ([], key) = None
   486   | gen_assoc eq ((keyi, xi) :: pairs, key) =
   517   | gen_assoc eq ((keyi, xi) :: pairs, key) =
   487       if eq (key, keyi) then Some xi else gen_assoc eq (pairs, key);
   518       if eq (key, keyi) then Some xi else gen_assoc eq (pairs, key);