This page states that the minimal complete definition of the Random class is "Nothing"
But if I don't provide them, they don't work:
data Color = Red | Blue deriving (Bounded, Show)
instance Random Color
yields the compiler warning:
test.hs:5:10: warning: [-Wmissing-methods]
• No explicit implementation for
‘randomR’ and ‘random’
• In the instance declaration for ‘Random Color’
|
5 | instance Random Color
and when I run the code I get an error:
*Main> let g = mkStdGen 100
*Main> (fst $ random g) :: Color
*** Exception: test.hs:5:10-21: No instance nor default method for class operation random
Why aren't random and randomR listed under the minimal complete definition?
That is a good question. And the answer is: you are using an older version of random, because starting with random-1.2 your code would not compile and would produce a compile time error, along the lines of:
• Could not deduce (UniformRange Color)
arising from a use of ‘System.Random.$dmrandomR’
from the context: RandomGen g
bound by the type signature for:
randomR :: forall g.
RandomGen g =>
Prior to random-1.2 there used to be no implementation for random and randomR, so compiler required implementation for those functions in a form of a compilation warning. However, starting with random-1.2 there is a default implementation that uses DefaultSignatures extension, which means your instance Random Color will compile without explicit implementation for random and randomR only if your type also has Uniform and UniformRange instances. For that reason compiler no longer shows random and randomR as required.
Edit
Starting with random-1.2.1 you can create an instance using nice helper functions uniformEnumM and uniformEnumRM:
import System.Random.Stateful
data Color = Red | Blue deriving (Bounded, Enum, Show)
instance Uniform Color where
uniformM = uniformEnumM
instance Uniform Color where
uniformRM = uniformEnumRM
instance Random Color
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