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 Weapon
s. If you derive Enum
for the type, a map to and from Int
s 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