As a general rule you write something like this:
do
x <- somethingThatReturnsIO
somethingElseThatReturnsIO $ pureFunction x
There is no way to get the "Int" out of an "IO Int", except to do something else in the IO Monad.
In monad terms, the above code desugars into
somethingThatReturnsIO >>= (x -> somethingElseThatReturnsIO $ pureFunction x)
The ">>=" operator (pronounced "bind") does the magic of converting the "IO Int" into an "Int", but it refuses to give that Int straight to you. It will only pass that value into another function as an argument, and that function must return another value in "IO". Meditate on the type of bind for the IO monad for a few minutes, and you may be enlightened:
>>= :: IO a -> (a -> IO b) -> IO b
The first argument is your initial "IO Int" value that "comboBoxGetActive" is returning. The second is a function that takes the Int value and turns it into some other IO value. Thus you can process the Int, but the results of doing so never escape from the IO monad.
(Of course there is the infamous "unsafePerformIO", but at your level of knowledge you may be certain that if you use it then you are doing it wrong.)
(Actually the desugaring is rather more complicated to allow for failed pattern matches. But you can pretend what I wrote is true)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…