[Haskell-cafe] mixing wxhaskell state and file io

Matthew Brecknell haskell at brecknell.org
Sun Feb 4 21:03:05 EST 2007

Martin DeMello said:
> I'm having a lot of trouble mixing file io and wxhaskell's
> varCreate/Get/Set functions. I have functions
> readWords :: String -> IO WordMap
> wordGrid :: WordMap -> Layout
> And within my GUI code, the following compiles (ignores the variable,
> basically):
>  words  <- varCreate (do {w <- readWords "words"; return w})

I'm not familiar with wxHaskell, but I don't think wxHaskell is your
problem here. It looks like you are confusing yourself with overuse of
"do" notation, and perhaps a lack of understanding of the monad laws.
Whenever you see this:

v <- expr
return v

You can replace it with just "expr". Your code above reduces to:

words <- varCreate (readWords "words")

So the variable you are creating has type (IO WordMap), when you
probably wanted it to have type WordMap. By itself, this compiles,
because IO actions are values as good as any other. The problem only
manifests when you combine it with code that tries to read the variable
as if it had type WordMap.

This is probably what you wanted (untested):

w <- readWords "words"
words <- varCreate w

Now, the variable has type WordMap.

>  wGrid  <- do w <- readWords "words"
>               return $ wordGrid w
> but I can't get the following (noncompiling code, but it shows what
> I'm trying to do) working:
>  wGrid  <- do w <- varGet words
>               return $ wordGrid w

With the above change, this should now work, though it might be clearer
to write this as:

wGrid <- liftM wordGrid $ varGet words

> Could someone give me a minimal example of reading in a list of words
> from a file, binding a wxHaskell variable to the list, and then
> mapping some GUI code over it?
> (Also, I'm making the base assumption that varSet and varGet are
> wxHaskell's analogue of the State monad - should I be looking at using
> StateT instead?)

The wxHaskell Var type is not quite like the State monad. It is a type
of mutable variable in the IO monad, much like the IORef type. Try to
avoid gratuitous use of mutable variables, as they can weaken your
ability to reason about your code. I'm not convinced you really need one
here. What problem are you trying to solve by using a mutable variable?

More information about the Haskell-Cafe mailing list