Similar: Haskell Random from Datatype
I have created a data type to contain the different weapons in the Rock Paper Scissor game.
data Weapon = Rock | Paper | Scissor
Now I would like to generate a random weapon which will be used by the computer against the user. I have take a look at the similar link I posted at the beginning but It seems too general for me.
I am able to generate random numbers from any other type. What I can get my head around is how to make my data type an instance of the Random class.
To generate a random Weapon, whether you make Weapon an instance of Random or not, what you need is a way to map numbers to Weapons. If you derive Enum for the type, a map to and from Ints is defined by the compiler. So you could define
randomWeapon :: RandomGen g => g -> (Weapon, g)
randomWeapon g = case randomR (0,2) g of
(r, g') -> (toEnum r, g')
for example. With an Enum instance, you can also easily make Weapon an instance of Random:
instance Random Weapon where
random g = case randomR (0,2) g of
(r, g') -> (toEnum r, g')
randomR (a,b) g = case randomR (fromEnum a, fromEnum b) g of
(r, g') -> (toEnum r, g')
If there is a possibility of adding or removing constructors from the type, the best way to keep the bounds for randomR in sync with the type is to also derive Bounded, as Joachim Breitner immediately suggested:
data Weapon
= Rock
| Paper
| Scissors
deriving (Bounded, Enum)
instance Random Weapon where
random g = case randomR (fromEnum (minBound :: Weapon), fromEnum (maxBound :: Weapon)) g of
(r, g') -> (toEnum r, g')
randomR (a,b) g = case randomR (fromEnum a, fromEnum b) g of
(r, g') -> (toEnum r, g')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With