Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fromEnum toEnum Instance?

Tags:

haskell

data Suit = Spade | Heart | Club | Diamond deriving (Eq, Ord, Enum, Show)

data Pip = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine    | Ten | Jack | Queen | King deriving (Eq, Ord, Enum, Show)

data Card = Card
       {suit :: Suit
       ,pip :: Pip
       } deriving (Eq,Ord, Show)

type Deck = [Card]

data EOBoard = EOBoard
         {foundations :: [Deck]
         ,columns     :: [Deck]
         ,reserve    :: [Deck]
         } deriving (Eq, Ord, Show)

instance Enum Card where

This is a solitaire data structure How can I make Card enumerable, with Enum instances from Card{suit = Spade, pip = Ace}, Card{suit = Spade, pip = Two} .. Card{suit = Heart, pip = Ace}.. Card{suit = Club, pip = Ace} .. Card{suit = Diamond, pip = Ace} ..Card{suit = Diamond, pip = King}.

like image 649
Joe Avatar asked Nov 18 '15 16:11

Joe


1 Answers

here is how I would do it (basically the @epsilonhalbe's idea):

data Suit
   = Spade | Heart | Club | Diamond
   deriving (Eq, Ord, Enum, Show, Bounded)

data Pip
   = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine
   | Ten | Jack | Queen | King
   deriving (Eq, Ord, Enum, Show, Bounded)

data Card = Card
     { suit :: Suit
     , pip :: Pip
     } deriving (Eq,Ord, Show, Bounded)

instance Enum Card where
  toEnum i =
    let (d,m) = i `divMod` (fromEnum (maxBound :: Pip) + 1)
    in Card (toEnum d) (toEnum m)
  fromEnum (Card s p) = fromEnum s * (fromEnum (maxBound :: Pip) + 1) + fromEnum p

this gives you:

λ> take 5 $ [minBound .. maxBound] :: [Card]
[Card {suit = Spade, pip = Ace},Card {suit = Spade, pip = Two},Card {suit = Spade, pip = Three},Card {suit = Spade, pip = Four},Card {suit = Spade, pip = Five}]

PS: now you should get all - sorry I messed up the maxBound forgetting the one extra

like image 126
Random Dev Avatar answered Oct 11 '22 14:10

Random Dev