This stuff is tricky for most newcomers I suspect (it was for me) x <- randomRIO(1,10) is "temporarilly" pulling the Integer you've named "x" out of the IO Integer it came from.
You can think of the console as being an input/output stream inside the IO monad, which is why it is allowed there. The fact is these are equivalent do x <- randomRIO(1,10) x : <expression> and randomRIO(1,10) >>= (\x -> x:<expression) They are the same meaning, and both are illegal for the same reason. (>>=) is the "bind" operator for Monads and it allows you to do things like sequence an IO operation or action, then examine the contents returned by that IO action, possibly performing some transformation on it with another function. x:<expression> is the function that takes a value "x" and applies the cons function (:) to build a list with <expression>. The problem is that the type system of Haskell will not allow this because the bind function (which is used by the "do" syntax behind the scenes) is of type: (>>=) :: (Monad m) => m a -> (a -> m b) -> m b Which states that the first argument to (>>=) is a Monad a, or in your case "randomRIO(1,10)" which is of type "IO Integer" IO being the "m" part of "m a" and "Integer" being the "a" part of "m a". What comes next is your consing function of (x : <expression>). This is of type [Integer]. So you failed to give it a function of type (a -> m b). (a -> m b) says that the input type to that function must be the same as the "contained" value of the first argument to (>>=) (because they're both of type 'a'). The "m b" part says that you must use the *same Monad* you used in the first parameter to (>>=) which is IO, not []. However the 'b' part says you can convert things of one type 'a' to things of another type 'b'. This is legal: randomRIO(1,10) >>= return (x : <expression>) However what you've got now is not a List of Integers ([Integer]) but an IO [Integer]. Because of the type of (>>=), you are not going to ever permanently escape that IO "wrapper" around your values you're interested in. The "return" is a function of the class Monad, that takes a value, and "wraps it up" in a monad. Based on the (>>=) function's type, the system can infer that you meant the IO monad here. You can even test this at the console: Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [7,99] Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [6,99] Prelude System.Random> randomRIO(1,10) >>= (\x -> return (x:[99])) [2,99] Prelude System.Random> :t randomRIO(1,10) >>= (\x -> return (x:[99])) randomRIO(1,10) >>= (\x -> return (x:[99])) :: (Num t, Random t) => IO [t] vs "randomRIO(1,10) >>= (\x -> x:[99])" Which doesn't pass the type checking of the system because [] is not the same monad as IO. Perhaps you'd do well for yourself by reading "Learn You A Haskell"? I've found it to be pretty darned good at explaining lots of haskell to newcomers. Dave On Wed, Jun 10, 2009 at 4:55 AM, 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 > > Now I have tried to write a Method which gives me a Number of random > numbers > the same way but it doesn't work. > > randomList :: Int -> [Integer] > randomList 0 = [] > randomList n = do > r <- randomRIO (1, 10) > r:randomList(n-1) > > It says Couldn't match expected type `IO t' against inferred type `[t]' > r <- randomRIO (1,10) causes an error. But why does it work on the console? > Is there a way to solve it another way? > -- > View this message in context: > http://www.nabble.com/Convert-IO-Int-to-Int-tp23940249p23960652.html > Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe