Skip to content

Commit 197991a

Browse files
committed
Modified export list
Added module header.
1 parent 5971ca7 commit 197991a

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module QueueStack
2+
( Stack (..)
3+
, Queue (..)
4+
, Pair (..)
5+
, CStack
6+
, CQueue
7+
) where
8+
9+
import Data.Foldable (foldl', toList)
10+
11+
class Foldable s => Stack s where
12+
push :: a -> s a -> s a
13+
pop :: s a -> (Maybe a, s a)
14+
emptyStack :: s a
15+
16+
class Foldable q => Queue q where
17+
enqueue :: a -> q a -> q a
18+
dequeue :: q a -> (Maybe a, q a)
19+
emptyQueue :: q a
20+
21+
-- A Pair consists of two of the same data structure, where the second is
22+
-- reversed. The pair represents the first structure prepended to the reverse
23+
-- of the second structure.
24+
newtype Pair f a = Pair (f a, f a)
25+
instance (Foldable s, Show a) => Show (Pair s a) where
26+
show = show . toList
27+
28+
instance Foldable s => Foldable (Pair s) where
29+
foldr f acc (Pair (sin, sout)) = let
30+
acc' = foldl (flip f) acc sout
31+
in foldr f acc' sin
32+
33+
sReverse :: Stack s => s a -> s a
34+
sReverse = foldl' (flip push) emptyStack
35+
36+
qReverse :: Queue q => q a -> q a
37+
qReverse = foldl' (flip enqueue) emptyQueue
38+
39+
qAppend :: Queue q => q a -> q a -> q a
40+
qAppend q1 q2 = foldr enqueue q2 q1
41+
42+
-- A pair of stacks behaves like a queue
43+
instance Stack s => Queue (Pair s) where
44+
enqueue elem (Pair (sin, sout)) = Pair (push elem sin, sout)
45+
dequeue (Pair (sin, sout)) = case pop sout of
46+
(Just x, sout') -> (Just x, Pair (sin, sout'))
47+
(Nothing, _) -> let
48+
(elem, sout') = pop . sReverse $ sin
49+
in (elem, Pair (emptyStack, sout'))
50+
emptyQueue = Pair (emptyStack, emptyStack)
51+
52+
-- A pair of Queues can behave like a stack
53+
instance Queue q => Stack (Pair q) where
54+
push elem (Pair (qin, qout)) = Pair (enqueue elem qin, qout)
55+
pop (Pair (qin, qout)) = case dequeue qin of
56+
(Nothing, _) -> let
57+
(elem, qout') = dequeue qout
58+
in (elem, Pair (emptyQueue, qout'))
59+
(Just _, _) -> pop . Pair $ (emptyQueue, qout `qAppend` qReverse qin)
60+
emptyStack = Pair (emptyQueue, emptyQueue)
61+
62+
-- The canonical stack type is a list
63+
type CStack = []
64+
-- The canonical queue type is a pair of lists
65+
type CQueue = Pair []
66+
67+
instance Stack [] where
68+
push = (:)
69+
pop [] = (Nothing, [])
70+
pop xs = (Just $ head xs, tail xs)
71+
emptyStack = []

0 commit comments

Comments
 (0)