Home > Software design >  Why does Random class have no minimal complete definition
Why does Random class have no minimal complete definition

Time:09-28

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?

CodePudding user response:

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 ofSystem.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
  • Related