On Wed, Jun 10, 2009 at 12:55 PM, ptrash <ptr...@web.de> wrote: > > Hi, > > I have tried on the console to write > > x <- randomRIO(1,10) > :t x > > Everythings fine and the type of x is > x :: Integer >
The type of x *in the context of an IO computation* is Integer. GHCi is basically an IO computation. Another example: foo :: Integer -> Integer foo x = x+1 main :: IO () main = do x <- randomRIO (1,10) print (foo x) This is fine. In the context of the IO computation "main", x is bound to the result of "randomRIO (1,10)", and you can pass it to functions expecting Integer values (not IO Integer!). So in this way, and this way only, you can access the Integer returned by an IO action. You can *not* access the Integer returned by an IO action from within a normal function, *only* by by binding it to a variable (with "<-") inside *another IO action*. I'm not sure what text you're using to learn Haskell, but a very basic and fundamental property of Haskell (and indeed 99% of why it's cool, IMO) is that code which does side effects (like reading from a global random number seed), and code which does not do side effects (i.e. functions which always return the same result given the same input) are kept extremely separate. This appears to be the source of your confusion. It's simply not possible to do side effect inside a normal function, just like it's not possible to cast an arbitrary integer to a pointer in Java - the language is designed to not require it, and the benefits of being able to trust that your program obeys certain properties are worth it. >randomList :: Int -> [Integer] >randomList 0 = [] >randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) In this code you're trying to do side effects from within a pure function. This is *not* allowed. You must either make randomList an IO action (i.e returning IO [Integer]), or remove any impurities from its implementation. For example you can make randomList take a randon number generator and use the random number generator to produce random values: randomList :: (RandomGen g) -> Int -> g -> [Integer] randomList 0 _ = [] randomList n generator = r : randomList (n-1) newGenerator where (r, newGenerator) = randomR (1,10) generator This is totally pure, since if you pass in the same random number generator multiple times, you'll get the exact same result. Note that randomR returns a random values and a new random number generator (you wouldn't want to pass along the same one in the recursive call to randomList as that would give you an identical random number each time you use it!). So where do you get the random number generator from? Well one way is to make your own using "mkStdGen", which produces one from a seed (it will give you an identical one given an identical seed). Another way is to use "newStdGen" to generate one from within an IO action: main :: IO () main = do generator <- newStdGen print ( randomList 10 generator ) The point, though, is that things having side effects (such as newStdGen) can only be used in the context of something else having side effects. So the "IO" type is "contagious", as soon as you use it in a function, then that function must also return IO, and so on for anything using *that* function and son. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe