75 val change: 'a ref -> ('a -> 'a) -> unit |
71 val change: 'a ref -> ('a -> 'a) -> unit |
76 val setmp: 'a ref -> 'a -> ('b -> 'c) -> 'b -> 'c |
72 val setmp: 'a ref -> 'a -> ('b -> 'c) -> 'b -> 'c |
77 val conditional: bool -> (unit -> unit) -> unit |
73 val conditional: bool -> (unit -> unit) -> unit |
78 |
74 |
79 (*lists*) |
75 (*lists*) |
80 exception LIST of string |
76 exception UnequalLengths |
81 val hd: 'a list -> 'a |
|
82 val tl: 'a list -> 'a list |
|
83 val cons: 'a -> 'a list -> 'a list |
77 val cons: 'a -> 'a list -> 'a list |
84 val single: 'a -> 'a list |
78 val single: 'a -> 'a list |
85 val append: 'a list -> 'a list -> 'a list |
79 val append: 'a list -> 'a list -> 'a list |
86 val rev_append: 'a list -> 'a list -> 'a list |
|
87 val apply: ('a -> 'a) list -> 'a -> 'a |
80 val apply: ('a -> 'a) list -> 'a -> 'a |
88 val foldl: ('a * 'b -> 'a) -> 'a * 'b list -> 'a |
|
89 val foldr: ('a * 'b -> 'b) -> 'a list * 'b -> 'b |
|
90 val foldr1: ('a * 'a -> 'a) -> 'a list -> 'a |
81 val foldr1: ('a * 'a -> 'a) -> 'a list -> 'a |
91 val fold: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b |
82 val fold: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b |
92 val fold_rev: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b |
83 val fold_rev: ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b |
93 val foldl_map: ('a * 'b -> 'a * 'c) -> 'a * 'b list -> 'a * 'c list |
84 val foldl_map: ('a * 'b -> 'a * 'c) -> 'a * 'b list -> 'a * 'c list |
94 val foldln: ('a * int -> 'b -> 'b) -> 'a list -> 'b -> 'b |
85 val foldln: ('a * int -> 'b -> 'b) -> 'a list -> 'b -> 'b |
95 val length: 'a list -> int |
86 val unflat: 'a list list -> 'b list -> 'b list list |
96 val take: int * 'a list -> 'a list |
|
97 val drop: int * 'a list -> 'a list |
|
98 val splitAt: int * 'a list -> 'a list * 'a list |
87 val splitAt: int * 'a list -> 'a list * 'a list |
99 val dropwhile: ('a -> bool) -> 'a list -> 'a list |
88 val dropwhile: ('a -> bool) -> 'a list -> 'a list |
100 val nth_elem: int * 'a list -> 'a |
|
101 val map_nth_elem: int -> ('a -> 'a) -> 'a list -> 'a list |
89 val map_nth_elem: int -> ('a -> 'a) -> 'a list -> 'a list |
102 val last_elem: 'a list -> 'a |
|
103 val split_last: 'a list -> 'a list * 'a |
90 val split_last: 'a list -> 'a list * 'a |
104 val nth_update: 'a -> int * 'a list -> 'a list |
91 val nth_update: 'a -> int * 'a list -> 'a list |
105 val find_index: ('a -> bool) -> 'a list -> int |
92 val find_index: ('a -> bool) -> 'a list -> int |
106 val find_index_eq: ''a -> ''a list -> int |
93 val find_index_eq: ''a -> ''a list -> int |
107 val find_first: ('a -> bool) -> 'a list -> 'a option |
94 val find_first: ('a -> bool) -> 'a list -> 'a option |
108 val get_first: ('a -> 'b option) -> 'a list -> 'b option |
95 val get_first: ('a -> 'b option) -> 'a list -> 'b option |
109 val flat: 'a list list -> 'a list |
|
110 val unflat: 'a list list -> 'b list -> 'b list list |
|
111 val seq: ('a -> unit) -> 'a list -> unit |
|
112 val separate: 'a -> 'a list -> 'a list |
96 val separate: 'a -> 'a list -> 'a list |
113 val replicate: int -> 'a -> 'a list |
97 val replicate: int -> 'a -> 'a list |
114 val multiply: 'a list * 'a list list -> 'a list list |
98 val multiply: 'a list * 'a list list -> 'a list list |
115 val product: 'a list -> 'b list -> ('a * 'b) list |
99 val product: 'a list -> 'b list -> ('a * 'b) list |
116 val filter: ('a -> bool) -> 'a list -> 'a list |
|
117 val filter_out: ('a -> bool) -> 'a list -> 'a list |
100 val filter_out: ('a -> bool) -> 'a list -> 'a list |
118 val mapfilter: ('a -> 'b option) -> 'a list -> 'b list |
|
119 val map2: ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list |
101 val map2: ('a * 'b -> 'c) -> 'a list * 'b list -> 'c list |
120 val exists2: ('a * 'b -> bool) -> 'a list * 'b list -> bool |
102 val exists2: ('a * 'b -> bool) -> 'a list * 'b list -> bool |
121 val forall2: ('a * 'b -> bool) -> 'a list * 'b list -> bool |
103 val forall2: ('a * 'b -> bool) -> 'a list * 'b list -> bool |
122 val seq2: ('a * 'b -> unit) -> 'a list * 'b list -> unit |
104 val seq2: ('a * 'b -> unit) -> 'a list * 'b list -> unit |
123 val ~~ : 'a list * 'b list -> ('a * 'b) list |
105 val ~~ : 'a list * 'b list -> ('a * 'b) list |
260 val pwd: unit -> string |
242 val pwd: unit -> string |
261 |
243 |
262 (*misc*) |
244 (*misc*) |
263 val make_keylist: ('a -> 'b) -> 'a list -> ('a * 'b) list |
245 val make_keylist: ('a -> 'b) -> 'a list -> ('a * 'b) list |
264 val keyfilter: ('a * ''b) list -> ''b -> 'a list |
246 val keyfilter: ('a * ''b) list -> ''b -> 'a list |
265 val partition: ('a -> bool) -> 'a list -> 'a list * 'a list |
|
266 val partition_eq: ('a * 'a -> bool) -> 'a list -> 'a list list |
247 val partition_eq: ('a * 'a -> bool) -> 'a list -> 'a list list |
267 val partition_list: (int -> 'a -> bool) -> int -> int -> 'a list -> 'a list list |
248 val partition_list: (int -> 'a -> bool) -> int -> int -> 'a list -> 'a list list |
268 val gensym: string -> string |
249 val gensym: string -> string |
269 val scanwords: (string -> bool) -> string list -> string list |
250 val scanwords: (string -> bool) -> string list -> string list |
270 end; |
251 end; |
271 |
252 |
272 structure Library: LIBRARY = |
253 signature LIBRARY_CLOSED = |
|
254 sig |
|
255 include LIBRARY |
|
256 |
|
257 val the: 'a option -> 'a |
|
258 val if_none: 'a option -> 'a -> 'a |
|
259 val is_some: 'a option -> bool |
|
260 val apsome: ('a -> 'b) -> 'a option -> 'b option |
|
261 |
|
262 val rev_append: 'a list -> 'a list -> 'a list |
|
263 val foldl: ('a * 'b -> 'a) -> 'a * 'b list -> 'a |
|
264 val foldr: ('a * 'b -> 'b) -> 'a list * 'b -> 'b |
|
265 val take: int * 'a list -> 'a list |
|
266 val drop: int * 'a list -> 'a list |
|
267 val nth_elem: int * 'a list -> 'a |
|
268 val last_elem: 'a list -> 'a |
|
269 val flat: 'a list list -> 'a list |
|
270 val seq: ('a -> unit) -> 'a list -> unit |
|
271 val partition: ('a -> bool) -> 'a list -> 'a list * 'a list |
|
272 val filter: ('a -> bool) -> 'a list -> 'a list |
|
273 val mapfilter: ('a -> 'b option) -> 'a list -> 'b list |
|
274 end; |
|
275 |
|
276 structure Library: LIBRARY_CLOSED = |
273 struct |
277 struct |
274 |
278 |
275 |
279 |
276 (** functions **) |
280 (** functions **) |
277 |
281 |
486 |
482 |
487 fun foldln f xs e = fst (foldl (fn ((e,i), x) => (f (x,i) e, i+1)) ((e,1),xs)); |
483 fun foldln f xs e = fst (foldl (fn ((e,i), x) => (f (x,i) e, i+1)) ((e,1),xs)); |
488 |
484 |
489 (* basic list functions *) |
485 (* basic list functions *) |
490 |
486 |
491 (*length of a list, should unquestionably be a standard function*) |
|
492 local fun length1 (n, []) = n (*TAIL RECURSIVE*) |
|
493 | length1 (n, x :: xs) = length1 (n + 1, xs) |
|
494 in fun length l = length1 (0, l) end; |
|
495 |
|
496 (*take the first n elements from a list*) |
487 (*take the first n elements from a list*) |
497 fun take (n, []) = [] |
488 fun take (n, []) = [] |
498 | take (n, x :: xs) = |
489 | take (n, x :: xs) = |
499 if n > 0 then x :: take (n - 1, xs) else []; |
490 if n > 0 then x :: take (n - 1, xs) else []; |
500 |
491 |
511 fun dropwhile P [] = [] |
502 fun dropwhile P [] = [] |
512 | dropwhile P (ys as x::xs) = if P x then dropwhile P xs else ys; |
503 | dropwhile P (ys as x::xs) = if P x then dropwhile P xs else ys; |
513 |
504 |
514 (*return nth element of a list, where 0 designates the first element; |
505 (*return nth element of a list, where 0 designates the first element; |
515 raise EXCEPTION if list too short*) |
506 raise EXCEPTION if list too short*) |
516 fun nth_elem NL = |
507 fun nth_elem (i,xs) = List.nth(xs,i); |
517 (case drop NL of |
|
518 [] => raise LIST "nth_elem" |
|
519 | x :: _ => x); |
|
520 |
508 |
521 fun map_nth_elem 0 f (x :: xs) = f x :: xs |
509 fun map_nth_elem 0 f (x :: xs) = f x :: xs |
522 | map_nth_elem n f (x :: xs) = x :: map_nth_elem (n - 1) f xs |
510 | map_nth_elem n f (x :: xs) = x :: map_nth_elem (n - 1) f xs |
523 | map_nth_elem _ _ [] = raise LIST "map_nth_elem"; |
511 | map_nth_elem _ _ [] = raise Subscript; |
524 |
512 |
525 (*last element of a list*) |
513 (*last element of a list*) |
526 fun last_elem [] = raise LIST "last_elem" |
514 val last_elem = List.last; |
527 | last_elem [x] = x |
|
528 | last_elem (_ :: xs) = last_elem xs; |
|
529 |
515 |
530 (*rear decomposition*) |
516 (*rear decomposition*) |
531 fun split_last [] = raise LIST "split_last" |
517 fun split_last [] = raise Empty |
532 | split_last [x] = ([], x) |
518 | split_last [x] = ([], x) |
533 | split_last (x :: xs) = apfst (cons x) (split_last xs); |
519 | split_last (x :: xs) = apfst (cons x) (split_last xs); |
534 |
520 |
535 (*update nth element*) |
521 (*update nth element*) |
536 fun nth_update x n_xs = |
522 fun nth_update x n_xs = |
537 (case splitAt n_xs of |
523 (case splitAt n_xs of |
538 (_,[]) => raise LIST "nth_update" |
524 (_,[]) => raise Subscript |
539 | (prfx, _ :: sffx') => prfx @ (x :: sffx')) |
525 | (prfx, _ :: sffx') => prfx @ (x :: sffx')) |
540 |
526 |
541 (*find the position of an element in a list*) |
527 (*find the position of an element in a list*) |
542 fun find_index pred = |
528 fun find_index pred = |
543 let fun find _ [] = ~1 |
529 let fun find _ [] = ~1 |
563 |
549 |
564 fun unflat (xs :: xss) ys = |
550 fun unflat (xs :: xss) ys = |
565 let val (ps,qs) = splitAt(length xs,ys) |
551 let val (ps,qs) = splitAt(length xs,ys) |
566 in ps :: unflat xss qs end |
552 in ps :: unflat xss qs end |
567 | unflat [] [] = [] |
553 | unflat [] [] = [] |
568 | unflat _ _ = raise LIST "unflat"; |
554 | unflat _ _ = raise UnequalLengths; |
569 |
555 |
570 (*like Lisp's MAPC -- seq proc [x1, ..., xn] evaluates |
556 (*like Lisp's MAPC -- seq proc [x1, ..., xn] evaluates |
571 (proc x1; ...; proc xn) for side effects*) |
557 (proc x1; ...; proc xn) for side effects*) |
572 fun seq (proc: 'a -> unit) : 'a list -> unit = |
558 val seq = List.app; |
573 let fun seqf [] = () |
|
574 | seqf (x :: xs) = (proc x; seqf xs) |
|
575 in seqf end; |
|
576 |
559 |
577 (*separate s [x1, x2, ..., xn] ===> [x1, s, x2, s, ..., s, xn]*) |
560 (*separate s [x1, x2, ..., xn] ===> [x1, s, x2, s, ..., s, xn]*) |
578 fun separate s (x :: (xs as _ :: _)) = x :: s :: separate s xs |
561 fun separate s (x :: (xs as _ :: _)) = x :: s :: separate s xs |
579 | separate _ xs = xs; |
562 | separate _ xs = xs; |
580 |
563 |
581 (*make the list [x, x, ..., x] of length n*) |
564 (*make the list [x, x, ..., x] of length n*) |
582 fun replicate n (x: 'a) : 'a list = |
565 fun replicate n (x: 'a) : 'a list = |
583 let fun rep (0, xs) = xs |
566 let fun rep (0, xs) = xs |
584 | rep (n, xs) = rep (n - 1, x :: xs) |
567 | rep (n, xs) = rep (n - 1, x :: xs) |
585 in |
568 in |
586 if n < 0 then raise LIST "replicate" |
569 if n < 0 then raise Subscript |
587 else rep (n, []) |
570 else rep (n, []) |
588 end; |
571 end; |
589 |
572 |
590 fun translate_string f = String.translate (f o String.str); |
573 fun translate_string f = String.translate (f o String.str); |
591 |
574 |
604 (*copy the list preserving elements that satisfy the predicate*) |
587 (*copy the list preserving elements that satisfy the predicate*) |
605 val filter = List.filter; |
588 val filter = List.filter; |
606 |
589 |
607 fun filter_out f = filter (not o f); |
590 fun filter_out f = filter (not o f); |
608 |
591 |
609 fun mapfilter (f: 'a -> 'b option) ([]: 'a list) = [] : 'b list |
592 val mapfilter = List.mapPartial; |
610 | mapfilter f (x :: xs) = |
|
611 (case f x of |
|
612 NONE => mapfilter f xs |
|
613 | SOME y => y :: mapfilter f xs); |
|
614 |
593 |
615 |
594 |
616 (* lists of pairs *) |
595 (* lists of pairs *) |
|
596 |
|
597 exception UnequalLengths; |
617 |
598 |
618 fun map2 _ ([], []) = [] |
599 fun map2 _ ([], []) = [] |
619 | map2 f (x :: xs, y :: ys) = (f (x, y) :: map2 f (xs, ys)) |
600 | map2 f (x :: xs, y :: ys) = (f (x, y) :: map2 f (xs, ys)) |
620 | map2 _ _ = raise LIST "map2"; |
601 | map2 _ _ = raise UnequalLengths; |
621 |
602 |
622 fun exists2 _ ([], []) = false |
603 fun exists2 _ ([], []) = false |
623 | exists2 pred (x :: xs, y :: ys) = pred (x, y) orelse exists2 pred (xs, ys) |
604 | exists2 pred (x :: xs, y :: ys) = pred (x, y) orelse exists2 pred (xs, ys) |
624 | exists2 _ _ = raise LIST "exists2"; |
605 | exists2 _ _ = raise UnequalLengths; |
625 |
606 |
626 fun forall2 _ ([], []) = true |
607 fun forall2 _ ([], []) = true |
627 | forall2 pred (x :: xs, y :: ys) = pred (x, y) andalso forall2 pred (xs, ys) |
608 | forall2 pred (x :: xs, y :: ys) = pred (x, y) andalso forall2 pred (xs, ys) |
628 | forall2 _ _ = raise LIST "forall2"; |
609 | forall2 _ _ = raise UnequalLengths; |
629 |
610 |
630 fun seq2 _ ([], []) = () |
611 fun seq2 _ ([], []) = () |
631 | seq2 f (x :: xs, y :: ys) = (f (x, y); seq2 f (xs, ys)) |
612 | seq2 f (x :: xs, y :: ys) = (f (x, y); seq2 f (xs, ys)) |
632 | seq2 _ _ = raise LIST "seq2"; |
613 | seq2 _ _ = raise UnequalLengths; |
633 |
614 |
634 (*combine two lists forming a list of pairs: |
615 (*combine two lists forming a list of pairs: |
635 [x1, ..., xn] ~~ [y1, ..., yn] ===> [(x1, y1), ..., (xn, yn)]*) |
616 [x1, ..., xn] ~~ [y1, ..., yn] ===> [(x1, y1), ..., (xn, yn)]*) |
636 fun [] ~~ [] = [] |
617 fun [] ~~ [] = [] |
637 | (x :: xs) ~~ (y :: ys) = (x, y) :: (xs ~~ ys) |
618 | (x :: xs) ~~ (y :: ys) = (x, y) :: (xs ~~ ys) |
638 | _ ~~ _ = raise LIST "~~"; |
619 | _ ~~ _ = raise UnequalLengths; |
639 |
620 |
640 (*inverse of ~~; the old 'split': |
621 (*inverse of ~~; the old 'split': |
641 [(x1, y1), ..., (xn, yn)] ===> ([x1, ..., xn], [y1, ..., yn])*) |
622 [(x1, y1), ..., (xn, yn)] ===> ([x1, ..., xn], [y1, ..., yn])*) |
642 fun split_list (l: ('a * 'b) list) = (map #1 l, map #2 l); |
623 val split_list = ListPair.unzip; |
643 |
624 |
644 fun equal_lists eq (xs, ys) = length xs = length ys andalso forall2 eq (xs, ys); |
625 fun equal_lists eq (xs, ys) = length xs = length ys andalso forall2 eq (xs, ys); |
645 |
626 |
646 |
627 |
647 (* prefixes, suffixes *) |
628 (* prefixes, suffixes *) |
820 val cs = explode s; |
801 val cs = explode s; |
821 val prfx_len = size s - size sfx; |
802 val prfx_len = size s - size sfx; |
822 in |
803 in |
823 if prfx_len >= 0 andalso implode (drop (prfx_len, cs)) = sfx then |
804 if prfx_len >= 0 andalso implode (drop (prfx_len, cs)) = sfx then |
824 implode (take (prfx_len, cs)) |
805 implode (take (prfx_len, cs)) |
825 else raise LIST "unsuffix" |
806 else raise Fail "unsuffix" |
826 end; |
807 end; |
827 |
808 |
828 (*remove prefix*) |
809 (*remove prefix*) |
829 fun unprefix prfx s = |
810 fun unprefix prfx s = |
830 let val (prfx', sfx) = splitAt (size prfx, explode s) |
811 let val (prfx', sfx) = splitAt (size prfx, explode s) |
831 in |
812 in |
832 if implode prfx' = prfx then implode sfx |
813 if implode prfx' = prfx then implode sfx |
833 else raise LIST "unprefix" |
814 else raise Fail "unprefix" |
834 end; |
815 end; |
835 |
816 |
836 fun replicate_string 0 _ = "" |
817 fun replicate_string 0 _ = "" |
837 | replicate_string 1 a = a |
818 | replicate_string 1 a = a |
838 | replicate_string k a = |
819 | replicate_string k a = |
1240 else keyfilter pairs searchkey; |
1221 else keyfilter pairs searchkey; |
1241 |
1222 |
1242 |
1223 |
1243 (*Partition list into elements that satisfy predicate and those that don't. |
1224 (*Partition list into elements that satisfy predicate and those that don't. |
1244 Preserves order of elements in both lists.*) |
1225 Preserves order of elements in both lists.*) |
1245 fun partition (pred: 'a->bool) (ys: 'a list) : ('a list * 'a list) = |
1226 val partition = List.partition; |
1246 let fun part ([], answer) = answer |
|
1247 | part (x::xs, (ys, ns)) = if pred(x) |
|
1248 then part (xs, (x::ys, ns)) |
|
1249 else part (xs, (ys, x::ns)) |
|
1250 in part (rev ys, ([], [])) end; |
|
1251 |
1227 |
1252 |
1228 |
1253 fun partition_eq (eq:'a * 'a -> bool) = |
1229 fun partition_eq (eq:'a * 'a -> bool) = |
1254 let fun part [] = [] |
1230 let fun part [] = [] |
1255 | part (x::ys) = let val (xs, xs') = partition (apl(x, eq)) ys |
1231 | part (x::ys) = let val (xs, xs') = partition (apl(x, eq)) ys |