Last active
February 3, 2018 04:39
-
-
Save throughnothing/d7cf35643964636a1b85cbd1823707c2 to your computer and use it in GitHub Desktop.
Deck of things...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CardDeck | |
( Card | |
, CardDeck | |
, mkCardDeck | |
, Suit | |
, Rank | |
) where | |
import Prelude (class Eq, class Ord, class Show, ($), bind, pure) | |
import Data.Generic.Rep.Show (genericShow) | |
import Data.Generic.Rep (class Generic) | |
import Data.List (List(..), fromFoldable) | |
import Data.NonEmpty ((:|)) | |
import Partial.Unsafe (unsafePartialBecause) | |
import Deck (Deck, Shuffled, Unshuffled, mkDeck) | |
-- | Type alias for a shuffled deck of cards | |
type CardDeck = Deck Shuffled Card | |
data Suit = Clubs | Diamonds | Hearts | Spades | |
derive instance suitEq :: Eq Suit | |
derive instance suitOrd :: Ord Suit | |
derive instance genericSuit :: Generic Suit _ | |
instance showSuit :: Show Suit where show = genericShow | |
data Rank | |
= Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | |
derive instance rankEq :: Eq Rank | |
derive instance rankOrd :: Ord Rank | |
derive instance genericRank :: Generic Rank _ | |
instance showRank :: Show Rank where show = genericShow | |
data Card = Card Suit Rank | |
derive instance cardEq :: Eq Card | |
derive instance cardOrd :: Ord Card | |
derive instance genericCard :: Generic Card _ | |
instance showCard :: Show Card where show = genericShow | |
mkCardDeck :: Deck Unshuffled Card | |
mkCardDeck = unsafePartialBecause "We know we have a full deck here" deck | |
where | |
deck :: Partial => Deck Unshuffled Card | |
deck = let (Cons x xs) = deckList in mkDeck $ x :| xs | |
deckList :: List Card | |
deckList = fromFoldable $ do | |
suit <- [Clubs, Diamonds, Hearts, Spades] | |
rank <- [Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King] | |
pure $ Card suit rank |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Deck | |
( deckSize | |
, Deck | |
, head | |
, mkDeck | |
, Shuffled | |
, shuffle | |
, tail | |
, Unshuffled | |
) where | |
import Control.Monad.Gen (class MonadGen, chooseInt) | |
import Data.Foldable (class Foldable, foldMap, foldl, foldr) | |
import Data.Generic.Rep (class Generic) | |
import Data.Generic.Rep.Show (genericShow) | |
import Data.List (List(..), deleteAt, fromFoldable, index, length) | |
import Data.List (drop, take, (:)) | |
import Data.Maybe (Maybe(..), fromJust) | |
import Data.Monoid (mempty) | |
import Data.NonEmpty (NonEmpty(..), (:|)) | |
import Partial.Unsafe (unsafePartialBecause) | |
import Prelude (class Eq, class Ord, class Show, bind, mod, pure, ($), (+), (-), (<>)) | |
-- Data type to denote a Sorted Deck | |
data Unshuffled | |
-- Data type to denote a Shuffled Deck | |
data Shuffled | |
data Deck s a = Deck (NonEmpty List a) | |
derive instance genericDeck :: Generic (Deck s a) _ | |
instance showDeck :: Show a => Show (Deck s a) where show = genericShow | |
instance foldableDeck :: Foldable (Deck s) where | |
foldMap f (Deck ne) = foldMap f ne | |
foldl f b (Deck ne) = foldl f b ne | |
foldr f b (Deck ne) = foldr f b ne | |
deckSize :: ∀ s a. Deck s a -> Int | |
deckSize (Deck (NonEmpty x xs)) = (length xs) + 1 | |
head :: ∀ s a. Deck s a -> a | |
head (Deck (NonEmpty x _)) = x | |
tail :: ∀ s a. Deck s a -> Maybe (Deck s a) | |
tail (Deck (NonEmpty x Nil)) = Nothing | |
tail (Deck (NonEmpty x (Cons y ys))) = Just (Deck $ y :| ys) | |
mkDeck :: ∀ a. NonEmpty List a -> Deck Unshuffled a | |
mkDeck ne = Deck ne | |
shuffle :: ∀ a m. MonadGen m => Deck Unshuffled a -> m (Deck Shuffled a) | |
shuffle (Deck ne) = unsafePartialBecause "It's Safe™" do | |
(Cons x xs) <- shuffleList $ fromFoldable ne | |
pure $ Deck $ x :| xs | |
where | |
shuffleList :: Partial => List a -> m (List a) | |
shuffleList Nil = pure mempty | |
shuffleList xs = do | |
rand <- chooseInt 0 $ (length xs) - 1 | |
let y = fromJust $ index xs rand | |
ys <- shuffleList $ fromJust $ deleteAt rand xs | |
pure $ y:ys |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment