take IO output to another pure Haskell-function

Viewed 148

I am new to Haskell, also English is not my first language, so please do not rate this post down because of some typo or because the question is poorly formulated: for me this is a true struggle.

Anyway: I am trying to generate random coordinates (Int,Int) and then use it in another Haskell function. But I have some problems "exporting" the IO-functions result to the second pure-kind Haskell function.

Here is an example that I think and hope properly illustrate my problem:

genRandomPair = genRandNr

genRandNr :: IO (Int,Int)
genRandNr = do
    firstRandom <- randomRIO (1,10)
    secondRandom <- randomRIO (1,10)
    return (firstRandom,secondRandom)

If its not obvious it is the transgression from genRandNr to genRandomPair that is my problem.

I would be very thankful for all friendly input.

Please note: very advanced code will explanations won't really help me, since I am on a beginners level and until a week ago never worked with monads or IO in Haskell.

2 Answers

If you have am IO (Int,Int) value and a function that takes, say, (Int,Int), you can use fmap to map the impure result through your pure function:

fmap myPureFunction anImpureTuple

In general, though, you may want to factor out the non-deterministic part of your code.

I realise that you're new to Haskell, but unfortunately, randomness in Haskell may not be a good beginner topic. Haskell explicitly distinguishes between pure functions and impure actions, and randomness is impure by nature.

Arriving at elegant decomposition of functions that rely on randomness requires understanding of some of Haskell's intermediary abstractions, such as Functors (in the case of fmap) or type classes (to understand RandomGen).

Idea of pure function in Haskell is if some pure function take the same arguments, it always return the same result. In your case, it means that your genRandomPair is just pair of Ints, this pair don't depend from time, day, your system and so on. Therefore, you can't just create random pair without IO.

But, you really can this with function unsafePerformIO or with other functions like it. It's usually not recommended, but, if you want...

Related