1 (* ========================================================================= *) |
1 (* ========================================================================= *) |
2 (* PRESERVING SHARING OF ML VALUES *) |
2 (* PRESERVING SHARING OF ML VALUES *) |
3 (* Copyright (c) 2005-2006 Joe Hurd, distributed under the BSD License *) |
3 (* Copyright (c) 2005-2006 Joe Hurd, distributed under the BSD License *) |
4 (* ========================================================================= *) |
4 (* ========================================================================= *) |
5 |
5 |
6 structure Sharing :> Sharing = |
6 structure Sharing :> Sharing = |
7 struct |
7 struct |
8 |
8 |
9 infix == |
9 infix == |
10 |
10 |
|
11 val op== = Portable.pointerEqual; |
|
12 |
11 (* ------------------------------------------------------------------------- *) |
13 (* ------------------------------------------------------------------------- *) |
12 (* Pointer equality. *) |
14 (* Option operations. *) |
13 (* ------------------------------------------------------------------------- *) |
15 (* ------------------------------------------------------------------------- *) |
14 |
16 |
15 val pointerEqual = Portable.pointerEqual; |
17 fun mapOption f xo = |
|
18 case xo of |
|
19 SOME x => |
|
20 let |
|
21 val y = f x |
|
22 in |
|
23 if x == y then xo else SOME y |
|
24 end |
|
25 | NONE => xo; |
16 |
26 |
17 val op== = pointerEqual; |
27 fun mapsOption f xo acc = |
|
28 case xo of |
|
29 SOME x => |
|
30 let |
|
31 val (y,acc) = f x acc |
|
32 in |
|
33 if x == y then (xo,acc) else (SOME y, acc) |
|
34 end |
|
35 | NONE => (xo,acc); |
18 |
36 |
19 (* ------------------------------------------------------------------------- *) |
37 (* ------------------------------------------------------------------------- *) |
20 (* List operations. *) |
38 (* List operations. *) |
21 (* ------------------------------------------------------------------------- *) |
39 (* ------------------------------------------------------------------------- *) |
22 |
40 |
23 fun map f = |
41 fun map f = |
24 let |
42 let |
25 fun m _ a_b [] = List.revAppend a_b |
43 fun m ys ys_xs xs = |
26 | m ys a_b (x :: xs) = |
44 case xs of |
27 let |
45 [] => List.revAppend ys_xs |
28 val y = f x |
46 | x :: xs => |
29 val ys = y :: ys |
47 let |
30 in |
48 val y = f x |
31 m ys (if x == y then a_b else (ys,xs)) xs |
49 val ys = y :: ys |
32 end |
50 val ys_xs = if x == y then ys_xs else (ys,xs) |
|
51 in |
|
52 m ys ys_xs xs |
|
53 end |
33 in |
54 in |
34 fn l => m [] ([],l) l |
55 fn xs => m [] ([],xs) xs |
35 end; |
56 end; |
|
57 |
|
58 fun maps f = |
|
59 let |
|
60 fun m acc ys ys_xs xs = |
|
61 case xs of |
|
62 [] => (List.revAppend ys_xs, acc) |
|
63 | x :: xs => |
|
64 let |
|
65 val (y,acc) = f x acc |
|
66 val ys = y :: ys |
|
67 val ys_xs = if x == y then ys_xs else (ys,xs) |
|
68 in |
|
69 m acc ys ys_xs xs |
|
70 end |
|
71 in |
|
72 fn xs => fn acc => m acc [] ([],xs) xs |
|
73 end; |
|
74 |
|
75 local |
|
76 fun revTails acc xs = |
|
77 case xs of |
|
78 [] => acc |
|
79 | x :: xs' => revTails ((x,xs) :: acc) xs'; |
|
80 in |
|
81 fun revMap f = |
|
82 let |
|
83 fun m ys same xxss = |
|
84 case xxss of |
|
85 [] => ys |
|
86 | (x,xs) :: xxss => |
|
87 let |
|
88 val y = f x |
|
89 val same = same andalso x == y |
|
90 val ys = if same then xs else y :: ys |
|
91 in |
|
92 m ys same xxss |
|
93 end |
|
94 in |
|
95 fn xs => m [] true (revTails [] xs) |
|
96 end; |
|
97 |
|
98 fun revMaps f = |
|
99 let |
|
100 fun m acc ys same xxss = |
|
101 case xxss of |
|
102 [] => (ys,acc) |
|
103 | (x,xs) :: xxss => |
|
104 let |
|
105 val (y,acc) = f x acc |
|
106 val same = same andalso x == y |
|
107 val ys = if same then xs else y :: ys |
|
108 in |
|
109 m acc ys same xxss |
|
110 end |
|
111 in |
|
112 fn xs => fn acc => m acc [] true (revTails [] xs) |
|
113 end; |
|
114 end; |
36 |
115 |
37 fun updateNth (n,x) l = |
116 fun updateNth (n,x) l = |
38 let |
117 let |
39 val (a,b) = Useful.revDivide l n |
118 val (a,b) = Useful.revDivide l n |
40 in |
119 in |