forcing IO operations

Andre W B Furtado awfurtado@uol.com.br
Tue, 19 Feb 2002 21:43:07 -0300


Curious problem...
Suppose MyMonad is a Monad other than the IO Monad. Consider the following
piece of code:

> f :: MyMonad ()
> f = action1

Now suppose also that ioToMyMonad converts an IO Monad to a MyMonad Monad:

> ioToMyMonad :: IO a -> MyMonad a
> ioToMyMonad = return . unsafePerformIO

Suppose also that action1 needs to perform some IO operation (called IO_op),
which returns IO (). In other words, action1 would be:

> action1 :: MyMonad ()
> action1 = do
>    -- MyMonad operations
>    ioToMyMonad $ IO_op
>    -- other MyMonad operations

When I run f (via runMyMonad or something like that), I noticed that the io
operation (IO_op) is not executed. I guess that this happens because of
laziness properties, since the value returned by IO_op is useless to
MyMonad. I have then two questions:

1. Does this really happen because of laziness properties?
2. Which is the best way to force IO_op to be performed? I tried the
following approach:

Step1: Change the type of IO_op from "IO ()" to "IO Bool" and make it
returns True.
Step2: Change action1 to

> action1 :: MyMonad Bool
> action1 = do
>    -- MyMonad operations
>    b <- ioToMyMonad $ IO_op
>    -- other MyMonad operations
>    return b

Step3: Change the type of f to MyMonad Bool
Step4: Finally, use this boolean somewhere after calling "runMyMonad", e.
g., printing it on the screen.

I'm sure this is not the best approach, so I'd really appreciate any
suggestions.

[I'm sending this mail to the HOpenGL list also because runMyMonad is being
called inside the display callback, so perhaps it may have something to do
with the problem]

Thanks a lot,
-- Andre