Commit | Line | Data |
---|---|---|
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 | |
6 | structure 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 |