[Haskell-cafe] Convert IO Int to Int
David Leimbach
leimy2k at gmail.com
Wed Jun 10 10:57:33 EDT 2009
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 <ptrash at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090610/172070d9/attachment.html
More information about the Haskell-Cafe
mailing list