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); |