[Haskell-cafe] Trapped by the Monads
robert dockins
robdockins at fastmail.fm
Tue Sep 20 11:33:51 EDT 2005
Mark Carter wrote:
> I'm puzzling out how to get a Bool from am IO Bool. I know I'm not
> supposed to, but I don't see any way around my predicament.
>
> The basic setup is: I have an edit box, and a panel. If you click the
> LMB on the panel when the edit box is checked, this means you want to
> move a graphical object around the panel. If it is unchecked, then
> clicking the LMB means you want to add a graphical object.
>
> The relevant bits I've managed to put together so far are:
>
> mainFrame = do -- main application frame
> streams <- varCreate []
> ...
> cbEdit <- checkBox p1 [text := "Edit Mode", on command ::= onCbEdit
> textlog] -- p1 is the panel, ignore textlog
> let isEditing = get cbEdit checked -- returns type IO Bool
> windowOnMouse p False {- no motion events -} (onMouse p streams
> isEditing)
> ...
> where
> onMouse w streams isEditChecked mouse = case mouse of
> MouseLeftDown pt mods ->
> if isEditChecked then
> findStream w streams pt
> else
> addStream w streams pt
> other -> skipCurrentEvent --
> unprocessed event: send up the window chain
>
> where
> -- define findStream and addStream
>
> The problem is that isEditChecked is of type IO Bool, not Bool. I
> presume that I should actually be taking a different (non-imperative)
> approach, and I'm wondering if anyone could suggest what that approach
> should be? Many apologies for being a clueless n00b.
Well, your onMouse function is acutally in the IO monad, so you can just
use the do notation. You can also get rid of the case, like so:
onMouse w streams isEditChecked (MouseLeftDown pt mods) =
do ec <- isEditChecked
if ec then ... else ...
onMouse _ _ _ _ = skipCurrentEvent
More information about the Haskell-Cafe
mailing list