Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting IO Int to Int

I've created a combobox from converting a xmlWidget to a comboBox with the function castTocomboBox and now I want to get the text or the index of the active item. The problem is that if I use the comboBoxGetActive function it returns an IO Int result and I need to know how can I obtain the Int value. I tried to read about monads so I could understand what one could do in a situation like this but I don't seem to understand. I appreciate all the help I can get. I should probably mention that I use Glade and gtk2hs.

like image 312
izayoi Avatar asked Nov 20 '10 22:11

izayoi


3 Answers

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)

like image 173
Paul Johnson Avatar answered Nov 09 '22 07:11

Paul Johnson


Well, there is unsafePerformIO: http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/System-IO-Unsafe.html#v:unsafePerformIO

(If you want to know how to find this method: Go to http://www.haskell.org/hoogle and search for the signature you need, here IO a -> a)

That said, you probably heard of "What happens in IO stays in IO". And there are very good reasons for this (just read the documentation of unsafePerformIO). So you very likely have a design problem, but in order to get help from experienced Haskellers (I'm certainly not), you need to describe your problem more detailed.

like image 26
Landei Avatar answered Nov 09 '22 08:11

Landei


To understand what those types are –step by step–, first look up what Maybe and List are:

data Maybe a = Nothing | Just a
data [a]     = [] | a : [a]

(Maybe a) is a different type than (a), like (Maybe Int) differs from (Int). Example values of the type (Maybe Int) are Just 5 and Nothing.

A List of (a)s can be written as ([ ] a) and as ([a]). Example values of ([Int]) are [1,7,42] and [ ].

Now, an (IO a) is a different thing than (a), too: It is an Input/Output-computation that calculates a value of type (a). In other words: it is a script or program, which has to be executed to generate a value of type (a). An Example of (IO String) is getLine, which reads a line of text from standard-input.

Now, the type of comboBoxGetActive is:

comboBoxGetActive :: ComboBoxClass self => self -> IO Int

That means, that comboBoxGetActive is a function (->) that maps from any type that has an instance of the type-class ComboBoxClass (primitive type-classes are somehow similar to java-interfaces) to an (IO Int). Each time, this function (->) is evaluated with the same input value of this type (self) (whatever that type is), it results in the same value: It is always the same value of type (IO Int), that means that it is always the same script. But when you execute that same script at different times, it could produce different values of type (Int).

The main function of your program has the type (IO ()), that means that the compiler and the runtime system evaluate the equations that you program in this functional language to the value of main, which will be executed as soon as you start the program.

like image 3
comonad Avatar answered Nov 09 '22 09:11

comonad