src/Pure/library.ML
changeset 19474 70223ad97843
parent 19461 d3bc9c1ff241
child 19483 55ee839198bd
equal deleted inserted replaced
19473:d87a8838afa4 19474:70223ad97843
    46   (*options*)
    46   (*options*)
    47   val the: 'a option -> 'a
    47   val the: 'a option -> 'a
    48   val these: 'a list option -> 'a list
    48   val these: 'a list option -> 'a list
    49   val the_default: 'a -> 'a option -> 'a
    49   val the_default: 'a -> 'a option -> 'a
    50   val the_list: 'a option -> 'a list
    50   val the_list: 'a option -> 'a list
    51   val if_none: 'a option -> 'a -> 'a
       
    52   val is_some: 'a option -> bool
    51   val is_some: 'a option -> bool
    53   val is_none: 'a option -> bool
    52   val is_none: 'a option -> bool
    54   val perhaps: ('a -> 'a option) -> 'a -> 'a
    53   val perhaps: ('a -> 'a option) -> 'a -> 'a
    55   val eq_opt: ('a * 'b -> bool) -> 'a option * 'b option -> bool
    54   val eq_opt: ('a * 'b -> bool) -> 'a option * 'b option -> bool
    56   val merge_opt: ('a * 'a -> bool) -> 'a option * 'a option -> 'a option
    55   val merge_opt: ('a * 'a -> bool) -> 'a option * 'a option -> 'a option
   114   val fold_rev: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
   113   val fold_rev: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
   115   val fold_map: ('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b
   114   val fold_map: ('a -> 'b -> 'c * 'b) -> 'a list -> 'b -> 'c list * 'b
   116   val foldr1: ('a * 'a -> 'a) -> 'a list -> 'a
   115   val foldr1: ('a * 'a -> 'a) -> 'a list -> 'a
   117   val foldl_map: ('a * 'b -> 'a * 'c) -> 'a * 'b list -> 'a * 'c list
   116   val foldl_map: ('a * 'b -> 'a * 'c) -> 'a * 'b list -> 'a * 'c list
   118   val flat: 'a list list -> 'a list
   117   val flat: 'a list list -> 'a list
       
   118   val maps: ('a -> 'b list) -> 'a list -> 'b list
   119   val unflat: 'a list list -> 'b list -> 'b list list
   119   val unflat: 'a list list -> 'b list -> 'b list list
   120   val burrow: ('a list -> 'b list) -> 'a list list -> 'b list list
   120   val burrow: ('a list -> 'b list) -> 'a list list -> 'b list list
   121   val fold_burrow: ('a list -> 'c -> 'b list * 'd) -> 'a list list -> 'c -> 'b list list * 'd
   121   val fold_burrow: ('a list -> 'c -> 'b list * 'd) -> 'a list list -> 'c -> 'b list list * 'd
   122   val chop: int -> 'a list -> 'a list * 'a list
   122   val chop: int -> 'a list -> 'a list * 'a list
   123   val splitAt: int * 'a list -> 'a list * 'a list
       
   124   val dropwhile: ('a -> bool) -> 'a list -> 'a list
   123   val dropwhile: ('a -> bool) -> 'a list -> 'a list
   125   val nth: 'a list -> int -> 'a
   124   val nth: 'a list -> int -> 'a
   126   val nth_update: int * 'a -> 'a list -> 'a list
   125   val nth_update: int * 'a -> 'a list -> 'a list
   127   val nth_map: int -> ('a -> 'a) -> 'a list -> 'a list
   126   val nth_map: int -> ('a -> 'a) -> 'a list -> 'a list
   128   val nth_list: 'a list list -> int -> 'a list
   127   val nth_list: 'a list list -> int -> 'a list
   350   | the_default x _ = x;
   349   | the_default x _ = x;
   351 
   350 
   352 fun the_list (SOME x) = [x]
   351 fun the_list (SOME x) = [x]
   353   | the_list _ = []
   352   | the_list _ = []
   354 
   353 
   355 (*strict!*)
       
   356 fun if_none NONE y = y
       
   357   | if_none (SOME x) _ = x;
       
   358 
       
   359 fun is_some (SOME _) = true
   354 fun is_some (SOME _) = true
   360   | is_some NONE = false;
   355   | is_some NONE = false;
   361 
   356 
   362 fun is_none (SOME _) = false
   357 fun is_none (SOME _) = false
   363   | is_none NONE = true;
   358   | is_none NONE = true;
   369   | eq_opt _ _ = false;
   364   | eq_opt _ _ = false;
   370 
   365 
   371 fun merge_opt _ (NONE, y) = y
   366 fun merge_opt _ (NONE, y) = y
   372   | merge_opt _ (x, NONE) = x
   367   | merge_opt _ (x, NONE) = x
   373   | merge_opt eq (SOME x, SOME y) = if eq (x, y) then SOME y else raise Option;
   368   | merge_opt eq (SOME x, SOME y) = if eq (x, y) then SOME y else raise Option;
       
   369 
   374 
   370 
   375 (* exceptions *)
   371 (* exceptions *)
   376 
   372 
   377 val do_transform_failure = ref true;
   373 val do_transform_failure = ref true;
   378 
   374 
   585 
   581 
   586 fun chop 0 xs = ([], xs)
   582 fun chop 0 xs = ([], xs)
   587   | chop _ [] = ([], [])
   583   | chop _ [] = ([], [])
   588   | chop n (x :: xs) = chop (n - 1) xs |>> cons x;
   584   | chop n (x :: xs) = chop (n - 1) xs |>> cons x;
   589 
   585 
   590 fun splitAt (n, xs) = chop n xs;
       
   591 
       
   592 (*take the first n elements from a list*)
   586 (*take the first n elements from a list*)
   593 fun take (n, []) = []
   587 fun take (n, []) = []
   594   | take (n, x :: xs) =
   588   | take (n, x :: xs) =
   595       if n > 0 then x :: take (n - 1, xs) else [];
   589       if n > 0 then x :: take (n - 1, xs) else [];
   596 
   590 
   608 
   602 
   609 fun nth_list xss i = nth xss i handle Subscript => [];
   603 fun nth_list xss i = nth xss i handle Subscript => [];
   610 
   604 
   611 (*update nth element*)
   605 (*update nth element*)
   612 fun nth_update (n, x) xs =
   606 fun nth_update (n, x) xs =
   613     (case splitAt (n, xs) of
   607   (case chop n xs of
   614       (_, []) => raise Subscript
   608     (_, []) => raise Subscript
   615     | (prfx, _ :: sffx') => prfx @ (x :: sffx'))
   609   | (prfx, _ :: sffx') => prfx @ (x :: sffx'));
   616 
   610 
   617 fun nth_map 0 f (x :: xs) = f x :: xs
   611 fun nth_map 0 f (x :: xs) = f x :: xs
   618   | nth_map n f (x :: xs) = x :: nth_map (n - 1) f xs
   612   | nth_map n f (x :: xs) = x :: nth_map (n - 1) f xs
   619   | nth_map _ _ [] = raise Subscript;
   613   | nth_map _ _ [] = raise Subscript;
   620 
   614 
   663 fun eq_list _ ([], []) = true
   657 fun eq_list _ ([], []) = true
   664   | eq_list eq (x :: xs, y :: ys) = eq (x, y) andalso eq_list eq (xs, ys)
   658   | eq_list eq (x :: xs, y :: ys) = eq (x, y) andalso eq_list eq (xs, ys)
   665   | eq_list _ _ = false;
   659   | eq_list _ _ = false;
   666 
   660 
   667 val flat = List.concat;
   661 val flat = List.concat;
       
   662 
       
   663 fun maps f = flat o map f;
   668 
   664 
   669 fun unflat (xs :: xss) ys =
   665 fun unflat (xs :: xss) ys =
   670       let val (ps, qs) = chop (length xs) ys
   666       let val (ps, qs) = chop (length xs) ys
   671       in ps :: unflat xss qs end
   667       in ps :: unflat xss qs end
   672   | unflat [] [] = []
   668   | unflat [] [] = []
  1093 
  1089 
  1094 (*balanced folding; avoids deep nesting*)
  1090 (*balanced folding; avoids deep nesting*)
  1095 fun fold_bal f [x] = x
  1091 fun fold_bal f [x] = x
  1096   | fold_bal f [] = raise Balance
  1092   | fold_bal f [] = raise Balance
  1097   | fold_bal f xs =
  1093   | fold_bal f xs =
  1098       let val (ps,qs) = splitAt(length xs div 2, xs)
  1094       let val (ps, qs) = chop (length xs div 2) xs
  1099       in  f (fold_bal f ps, fold_bal f qs)  end;
  1095       in  f (fold_bal f ps, fold_bal f qs)  end;
  1100 
  1096 
  1101 (*construct something of the form f(...g(...(x)...)) for balanced access*)
  1097 (*construct something of the form f(...g(...(x)...)) for balanced access*)
  1102 fun access_bal (f, g, x) n i =
  1098 fun access_bal (f, g, x) n i =
  1103   let fun acc n i =     (*1<=i<=n*)
  1099   let fun acc n i =     (*1<=i<=n*)