Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / basic / fold.fun
1 (* Copyright (C) 2009 Matthew Fluet.
2 * Copyright (C) 1999-2006, 2008 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9 functor Fold (S: FOLD_STRUCTS): FOLD =
10 struct
11
12 open S
13
14 fun foldi (l: 'a t, b, f) =
15 #1 (fold (l, (b, 0: int), fn (x, (b, i)) => (f (i, x, b), i + 1)))
16
17 fun foreachi (l, f) = foldi (l, (), fn (i, x, ()) => f (i, x))
18
19 fun foreach (l, f: 'a elt -> unit) = fold (l, (), f o #1)
20
21 fun last l =
22 case fold (l, NONE, SOME o #1) of
23 NONE => Error.bug "Fold.last"
24 | SOME x => x
25
26 fun length l = fold (l, 0: int, fn (_, n) => n + 1)
27
28 fun mapi (l, f) = rev (foldi (l, [], fn (i, x, l) => f (i, x) :: l))
29
30 fun map (l, f) = mapi (l, f o #2)
31
32 fun layout f l = Layout.list (map (l, f))
33
34 fun revKeepAllMap (l, f) =
35 fold (l, [], fn (x, ac) =>
36 case f x of
37 NONE => ac
38 | SOME y => y :: ac)
39
40 fun keepAllMap z = rev (revKeepAllMap z)
41
42 fun revKeepAll (l, f) =
43 fold (l, [], fn (x, ac) => if f x then x :: ac else ac)
44
45 fun keepAll z = rev (revKeepAll z)
46
47 fun revRemoveAll (l, f) =
48 fold (l, [], fn (x, ac) => if f x then ac else x :: ac)
49
50 fun removeAll z = rev (revRemoveAll z)
51
52 end