[Haskell-cafe] Automatic liftIO or how to write this shorter?

Gleb Popov 6yearold at gmail.com
Fri May 8 11:20:51 UTC 2015


Hello haskell-cafe@

I'm writing a GUI app in Haskell and bindings to the widget toolkit i'm
using in parallel. These bindings are very simple and all its functions
have return type (IO something).

So far so good, i wrote the following code to create an config window:

createConfigUI root = do
    box <- Box.add root

    -- first field
    addToPackEnd box =<< do
        f <- Fr.add box
        setPartText f Nothing "E-mail"
        setPartContent f Nothing =<< do
            box <- Box.add box

            addToPackEnd box =<< do
                e <- Ent.add box
                Ent.singleLineSet e True
                -- Here
                onEvent "changed,user" e $ do
                     reactOnUserInput e
                objectShow e
                return e

            objectShow box
            return box

        objectShow f
        return f

    -- next field
    addToPackEnd box =<< do
        ...

Initially, i was quite satisfied with flipped bind use for creating UI
elements and arranging them. Nested do scopes allow copypasting code
without renaming variables and also provide some visual representation on
widget hierarchy.

But at some point i need to return some stuff from some inner do block into
outmost. For example, at the line with comment "Here" i defined

let setText t = entrySet e t

and wanted to return it from whole createConfigUI action. Moreover,
createConfigUI have much more fields, for each of them i want to do the
same.

My initial thought was to wrap everything with runWriter and just call

tell setText

wherever i want to gather all setter functions into a list, but i can't do
this because i would need to put liftIO before every IO action all over the
place.

If only there was i way to turn an (IO a) into (MonadIO m => m a), it would
be easy.

Another solution is to make my bindings return (MonadIO m => m a). This
would be equal effort of plugging liftIO's everywhere, but at least it
would be hidden from user of bindings. I'd gone this way, but looked at gtk
bindings first and found that (IO a) is used there.

So, my questions are:

1. What would you recommend in my situation? Is it possible yield values
from inner do blocks into outer without much hassle?
2. If there is nothing wrong with switching bindings from (IO a) to MonadIO
typeclass, why not to do this for gtk, wxWidgets and nearly every FFI
binding?

Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150508/9a04000d/attachment.html>


More information about the Haskell-Cafe mailing list