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
 module Deck (
Deck, deal,
draw, drawN,
deckList, empty
) where
import System.Random
import Util
pick :: RandomGen r => [a] > r > (Int, r)
pick s = randomR (0, pred $ length s)
shuffle :: RandomGen r => [a] > r > [a]
shuffle [] _ = []
shuffle s r = x : shuffle l r' where
(n, r') = pick s r
(x, l) = pull s n
pool :: RandomGen r => [a] > r > [a]
pool s = rand where
rand r = s!!i : rand r' where
(i, r') = pick s r
newtype Deck a = Deck { deckList :: [a] }
deal :: RandomGen r => [a] > Bool > r > Deck a
deal s True = Deck . pool s
deal s False = Deck . shuffle s
draw :: Deck a > (a, Deck a)
draw (Deck []) = error "Deck.draw: empty deck"
draw (Deck (c:d)) = (c, Deck d)
drawN :: Int > Deck a > ([a], Deck a)
drawN n (Deck l) = (r, Deck l') where (r, l') = splitAt n l
empty :: Deck a > Bool
empty = null . deckList
