This repository was archived by the owner on Nov 1, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDequeue.hs
120 lines (98 loc) · 2.97 KB
/
Dequeue.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
--
--@@ An implemenation of Chris Okasaki's dequeues with O(1)
--@@ insert and delete.
--@@ See JFP vol 5 part 4.
--
module Dequeue (
Dequeue,
empty, snoc, tail, head, null,
cons, init, last,
size,
toList, fromList
) where
data Dequeue a = Q [a] [a] [a] [a] !Int !Int
instance (Eq a) => Eq (Dequeue a) where
Q l r _ _ _ _ == Q l' r' _ _ _ _ = l ++ reverse r == l' ++ reverse r'
instance (Show a) => Show (Dequeue a) where
showsPrec p (Q l r _ _ _ _) = showParen (p > 0) (showString "Dequeue " . showsPrec 0 (l ++ reverse r))
showsType (Q ~(x:_) _ _ _ _ _) = showString "(Dequeue " . showsType x . showsType ")"
c = 3 :: Int
empty :: Dequeue a
empty = Q [] [] [] [] 0 0
snoc :: a -> Dequeue a -> Dequeue a
snoc x (Q l r l' r' ln rn) =
tl1 l' $ \ l' ->
tl1 r' $ \ r' ->
makeQ l (x:r) l' r' ln (rn+1)
cons :: a -> Dequeue a -> Dequeue a
cons x (Q l r l' r' ln rn) =
tl1 l' $ \ l' ->
tl1 r' $ \ r' ->
makeQ (x:l) r l' r' (ln+1) rn
head :: Dequeue a -> a
head (Q [] [] _ _ _ _) = error "Dequeue.head: empty queue"
head (Q [] (x:r) _ _ _ _) = x
head (Q (x:_) _ _ _ _ _) = x
tail :: Dequeue a -> Dequeue a
tail (Q [] [] _ _ _ _) = error "Dequeue.tail: empty queue"
tail (Q [] _ _ _ _ _) = empty
tail (Q (_:l) r r' l' ln rn) =
tl2 l' $ \ l' ->
tl2 r' $ \ r' ->
makeQ l r r' l' (ln-1) rn
last :: Dequeue a -> a
last (Q [] [] _ _ _ _) = error "Dequeue.last: empty queue"
last (Q (x:r) [] _ _ _ _) = x
last (Q _ (x:_) _ _ _ _) = x
init :: Dequeue a -> Dequeue a
init (Q [] [] _ _ _ _) = error "Dequeue.init: empty queue"
init (Q _ [] _ _ _ _) = empty
init (Q l (_:r) r' l' ln rn) =
tl2 l' $ \ l' ->
tl2 r' $ \ r' ->
makeQ l r r' l' ln (rn-1)
makeQ :: [a] -> [a] -> [a] -> [a] -> Int -> Int -> Dequeue a
makeQ l r l' r' ln rn
| ln > c*rn + 1 =
let n = (ln+rn) `quot` 2
l' = take n l
r' = rot1 n r l
in Q l' r' l' r' (ln-n) (rn+n)
| rn > c*ln + 1 =
let n = (ln+rn) `quot` 2
l' = rot1 n l r
r' = take n r
in Q l' r' l' r' (ln+n) (rn-n)
| otherwise = Q l r l' r' ln rn
rot1 n l r =
if n >= c then
case l of x:xs -> x : rot1 (n-c) xs (drop c r)
else
rot2 l (drop n r) []
rot2 [] r a = rev r a
rot2 l r a | lessLength c r = l ++ rev r a
rot2 (x:l) r a = x : rot2 l (drop c r) (reverse (take c r) ++ a)
rev [] a = a
rev (x:xs) a = rev xs (x:a)
lessLength :: Int -> [a] -> Bool
lessLength n [] = False
lessLength 0 (_:_) = True
lessLength n (_:xs) = lessLength (n-1) xs
-- Take the tail, but avoid failing.
tl1 [] c = c []
tl1 (_:xs) c = c xs
tl2 [] c = c []
tl2 [_] c = c []
tl2 (_:_:xs) c = c xs
null :: Dequeue a -> Bool
null (Q [] [] _ _ _ _) = True
null _ = False
size :: Dequeue a -> Int
size (Q _ _ _ _ ln rn) = ln + rn
instance Functor Dequeue where
--map :: (a -> b) -> Dequeue a -> Dequeue b
map f (Q l r l' r' ln rn) = Q (Prelude.map f l) (Prelude.map f r) (Prelude.map f l') (Prelude.map f r') ln rn
toList :: Dequeue a -> [a]
toList (Q l r _ _ _ _) = l ++ reverse r
fromList :: [a] -> Dequeue a
fromList l = foldr cons empty l