Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / cml / util / fun-queue.sml
CommitLineData
7f918cf1
CE
1(* fun-queue.sml\r
2 * 2004 Matthew Fluet (mfluet@acm.org)\r
3 * Ported to MLton threads.\r
4 *)\r
5\r
6structure FunQueue : FUN_QUEUE =\r
7 struct\r
8 datatype 'a t = T of {front: 'a list, back: 'a list}\r
9\r
10 local\r
11 fun filterPrefix (xs, p) =\r
12 case xs of\r
13 [] => []\r
14 | y::ys => if p y\r
15 then filterPrefix (ys, p)\r
16 else xs\r
17 fun filter (xs, p) = List.filter (not o p) xs\r
18 fun filterRevAcc ((xs, zs), p) =\r
19 case xs of\r
20 [] => zs\r
21 | y::ys => if p y\r
22 then filterRevAcc ((ys, zs), p)\r
23 else filterRevAcc ((ys, y::zs), p)\r
24 fun filterRev (xs, p) = filterRevAcc ((xs, []), p)\r
25 in\r
26 fun cleanPrefix (T {front, back}, p) =\r
27 (case filterPrefix (front, p) of\r
28 [] => T {front = filterPrefix (List.rev(back), p),\r
29 back = []}\r
30 | front' => T {front = front',\r
31 back = back})\r
32 fun clean (T {front, back}, p) =\r
33 (case filter (front, p) of\r
34 [] => T {front = filterRev (back, p),\r
35 back = []}\r
36 | front' => T {front = front',\r
37 back = filter (back, p)})\r
38 fun cleanAndDeque (T {front, back}, p) =\r
39 (case filter (front, p) of\r
40 [] => (case filterRev(back, p) of\r
41 [] => (NONE,\r
42 T {front = [],\r
43 back = []})\r
44 | x::front' => (SOME x,\r
45 T {front = front',\r
46 back = []}))\r
47 | [x] => (SOME x,\r
48 T {front = filterRev (back, p),\r
49 back = []})\r
50 | x::front' => (SOME x,\r
51 T {front = front',\r
52 back = filter (back, p)}))\r
53 end\r
54\r
55 fun deque (T {front, back}) =\r
56 (case front of\r
57 [] => (case back of\r
58 [] => NONE\r
59 | l => let val l = List.rev l\r
60 in \r
61 case l of\r
62 [] => raise Fail "FunQueue.deque:impossible"\r
63 | x::front' => \r
64 SOME (x,\r
65 T {front = front',\r
66 back = []})\r
67 end)\r
68 | x::front' => SOME (x, T {front = front', back = back}))\r
69 \r
70 fun empty (T {front, back}) =\r
71 (case front of\r
72 [] => (case back of\r
73 [] => true\r
74 | _ => false)\r
75 | _ => false)\r
76 \r
77 fun enque (T {front, back, ...}, x) = \r
78 T {front = front, back = x::back}\r
79\r
80 fun enqueAndClean (q, y, p) =\r
81 clean (enque (q, y), p)\r
82\r
83 fun new () = T {front = [], back = []}\r
84\r
85 fun peek (T {front, back}) =\r
86 (case front of\r
87 [] => (case back of\r
88 [] => NONE\r
89 | l => let val l = List.rev l\r
90 in \r
91 case l of\r
92 [] => raise Fail "FunQueue.peek:impossible"\r
93 | x::_ => SOME x\r
94 end)\r
95 | x::_ => SOME x)\r
96 end\r