0

I am trying to print random number between 0 and 1 but the code is giving error. I'm unable to understand what am I doing wrong.

import System.Random
main = print (randomRIO (1,0))

error: • No instance for (Show (IO a0)) arising from a use of ‘print’ • In the expression: print (randomRIO (1, 0)) In an equation for ‘main’: main = print (randomRIO (1, 0)) | 2 | main = print (randomRIO (1,0)) | ^^^^^^^^^^^^^^^^^^^^^^^

error: • Ambiguous type variable ‘a0’ arising from a use of ‘randomRIO’ prevents the constraint ‘(Random a0)’ from being solved. Probable fix: use a type annotation to specify what ‘a0’ should be. These potential instances exist: instance Random Integer -- Defined in ‘System.Random’ instance Random Bool -- Defined in ‘System.Random’ instance Random Char -- Defined in ‘System.Random’ ...plus four others ...plus 29 instances involving out-of-scope types (use -fprint-potential-instances to see them all) • In the first argument of ‘print’, namely ‘(randomRIO (1, 0))’ In the expression: print (randomRIO (1, 0)) In an equation for ‘main’: main = print (randomRIO (1, 0))

error: • Ambiguous type variable ‘a0’ arising from the literal ‘1’ prevents the constraint ‘(Num a0)’ from being solved. Probable fix: use a type annotation to specify what ‘a0’ should be. These potential instances exist: instance Num Integer -- Defined in ‘GHC.Num’ instance Num Double -- Defined in ‘GHC.Float’ instance Num Float -- Defined in ‘GHC.Float’ ...plus two others ...plus 35 instances involving out-of-scope types (use -fprint-potential-instances to see them all) • In the expression: 1 In the first argument of ‘randomRIO’, namely ‘(1, 0)’ In the first argument of ‘print’, namely ‘(randomRIO (1, 0))’ | 2 | main = print (randomRIO (1,0)) | ^

1 Answer 1

6

Two Three problems:

print randomRIO (1,0)

Reads like the print function being given two arguments. Or, more technically, since application is left associative, it means the same as this:

(print randomRIO) (1,0)

If you wanted to give print only one argument, you would have to parenthesize it:

print (randomIO (1,0))

But that brings us to our second problem. randomRIO is an IO action, not a simple function. Its type (specialized for educational purposes) is

randomRIO :: (Int, Int) -> IO Int

Notice that the return value is of the form IO something? randomRIO (1,0) is an IO Int, but we want to print a plain Int. To extract the a from an IO a, you bind the function to a variable in a do block:

main = do
    r <- randomRIO (1,0)
    print r

I thought that was it, but (if you don't do this in ghci like I did) you get an ambiguous type variable warning because randomRIO doesn't know whether you want to pick a random Int or a random Double or what, and simply printing it is not enough to deduce that. So we have to specify:

main = do
    r <- randomRIO (1, 0)
    print (r :: Int)

(And come to think of it you probably wanted a Double anyway.)

We could have specified the type in a lot of different ways; on r, on the 1 or 0, or using r in a way that makes its type clear. Usually there are enough contextual clues in code that you don't need to annotate any expressions like this, as long as you annotate your top level functions.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer.. but I am still getting error: Ambiguous type variable ‘a0’ arising from a use of ‘randomRIO’
@RahulAgarwal ah oops, I tested in ghci which has special rules about that. Fixed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.