Haskell random number generation

I read chapter 9 (More input and more output) to learn about Haskell for Great Good. Now I'm going to learn how to generate random numbers in Haskell (this is so interesting!). Here is a quote from the book:

To manually create a random generator, use mkStdGenfunction. He has a type mkStdGen :: Int -> StdGen. It takes an integer and, based on this, gives us a random generator. Then let's try to use randomand mkStdGenintandem, to get (almost) random number.

ghci> random (mkStdGen 100)
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`Random a' arising from a use of `random' at <interactive>:1:0-20
Probable fix: add a type signature that fixes these type variable(s)

What is it? Ah, right, a function randomcan return a value of any type that is part of a type class random, so we need to tell Haskell which type we want. Also do not forget that it returns a random value and a random generator in pairs.

The problem is that I am not getting this error, in fact I can do the following:

*Main> :m + System.Random
*Main System.Random> random (mkStdGen 100)
(-3633736515773289454,693699796 2103410263)

So my question is why can I evaluate this expression without getting an exception?

+4
source share
1 answer

I would speculate and say that the default rules for GHCI have been extended since LYAH was written. This means that in cases where the type is ambiguous, GHCI tries to select a specific type. In this case, it looks like random (mkStdGen 100)the default (Integer, StdGen).

If, on the other hand, I make a test.hs file

import System.Random

foo = random (mkStdGen 100)

... and try loading it into GHCI, I get:

test.hs:3:7:
    No instance for (Random a0) arising from a use of ‘random’
    The type variable ‘a0’ is ambiguous
    Relevant bindings include
      foo :: (a0, StdGen) (bound at test.hs:3:1)
    Note: there are several potential instances:
      instance Random Bool -- Defined in ‘System.Random’
      instance Random Foreign.C.Types.CChar -- Defined in ‘System.Random’
      instance Random Foreign.C.Types.CDouble
        -- Defined in ‘System.Random’
      ...plus 33 others
    In the expression: random (mkStdGen 100)
    In an equation for ‘foo’: foo = random (mkStdGen 100)
Failed, modules loaded: none.

If I wanted to get the same result, I would have to fix the type foo, for example:

foo :: (Integer, StdGen)
foo = random (mkStdGen 100)

. 2.4.8 GHC

+10

All Articles