Skip to content

Commit 5971ca7

Browse files
committed
Implmenentes queue from stack, and stack from queue
Haskell Implements a Queue and Stack typeclass, and a Pair type. For any instance x of the Stack typeclass, Pair x is a Queue, and every instance x that is a Queue, Pair x is a Stack.
1 parent 6fddfba commit 5971ca7

File tree

1 file changed

+63
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)