#!/usr/bin/env stack {- stack --nix --resolver lts-11.15 --install-ghc runghc --package random -} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {- Problem: Create a string array containing a representation of the 52 cards in a standard deck, and then a second array that shuffles the 52 cards. Start with two string arrays of the cards and suits: Cards: 2, 3, 4, 5, 6, 7, 8, 9, 10, J, K, Q, A Suits: Clubs, Diamonds, Aces, Spades -} import System.Random import Control.Monad import Control.Applicative data Name = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | King | Queen | Ace deriving (Show, Enum, Bounded) names :: [Name] names = [ Two .. ] data Suit = Club | Diamond | Heart | Spade deriving (Show, Enum, Bounded) suits :: [Suit] suits = [ Club .. ] type Card = (Name, Suit) instance Random Suit where randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of (x, g') -> (toEnum x, g') random g = randomR (minBound, maxBound) g instance Random Name where randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of (x, g') -> (toEnum x, g') random g = randomR (minBound, maxBound) g -- Dot product is same as 'liftA2 (,)' allCards :: [Card] allCards = liftA2 (,) names suits shuffle' :: [Card] -> _ shuffle' (i:is) xs = (last firsts) : shuffle' is (init firsts ++ rest) where (firsts, rest) = splitAt (i `mod` length xs) xs shuffle g xs = shuffle (randoms g) xs main :: IO [()] main = do g <- getStdGen let namesLength = length names let randomNames = map fromEnum $ take namesLength $ randomRs (0, namesLength-1) g let suitsLength = length suits let randomSuits = map fromEnum $ take suitsLength $ randomRs (0, suitsLength-1) g sequence $ map (putStrLn.show) $ liftA2 (,) randomNames randomSuits