[Haskell-beginners] Problem in Gtk2Hs/Glade
Daniel Fischer
daniel.is.fischer at web.de
Mon Oct 11 13:48:22 EDT 2010
On Monday 11 October 2010 18:19:24, Tom Hobbs wrote:
> Hi all,
>
> I playing around with simple cell automaton (Conway's Game Of Life).
> I've got working code which prints everything out nicely to the
> terminal, I'm trying to wrap everything in a nice GUI using Glade and
> Gtk2Hs.
>
> In order to create my world, I have a function defined as;
>
> makeWorld :: Int -> [(Int,Int)]
>
> Which accepts an Int, representing the size of the world, then then
> outs the world itself - note the world is always assumed to be square.
> The list contains pairs such that the first element of the pair is
> the index (such as for an array) and the second is the value at that
> position. For right or wrong, that's how my (working) Game Of Life
> has been implemented. The problem comes in the Gtk2Hs code...
>
> main = do
> initGUI
> Just xml <- xmlNew "gameOfLife.glade"
> window <- xmlGetWidget xml castToWindow "mainWindow"
> onDestroy window mainQuit
> quitButton <- xmlGetWidget xml castToButton "quitButton"
> onClicked quitButton $ do
> widgetDestroy window
> setWorldSize <- xmlGetWidget xml castToButton "setWorldSize"
> sizeBox <- xmlGetWidget xml castToEntry "worldSize"
> onClicked setWorldSize $ do
> canvas <- xmlGetWidget xml castToDrawingArea "world"
> let size = (read (get sizeBox entryText) :: Int)
> cellworld <- makeWorld size
> printWorld cellworld
> widgetShowAll window
> mainGUI
>
> The above function does not compile under GHC because;
>
> gameOfLife.hs:27:20:
> Couldn't match expected type `String'
> against inferred type `IO String'
> In the first argument of `read', namely `(get sizeBox entryText)'
> In the expression: (read (get sizeBox entryText) :: Int)
> In the definition of `size':
> size = (read (get sizeBox entryText) :: Int)
get sizeBox entryText
is an IO-action which, when executed gets the entry-text from sizeBox.
The type is IO String.
What you want is the entry-text, hence the result of the IO-action, so you
have to run that action and bind its result to a name, for example
text <- get sizeBox entryText
let size = read text
or, on one line
size <- fmap read (get sizeBox entryText)
>
> gameOfLife.hs:28:2:
> Couldn't match expected type `[(Int, Int)]'
> against inferred type `IO (Int, Int)'
> In a stmt of a 'do' expression: cellworld <- makeWorld size
> In the second argument of `($)', namely
> `do { canvas <- xmlGetWidget xml castToDrawingArea "world";
> let size = (read (get sizeBox entryText) :: Int);
> cellworld <- makeWorld size;
> printWorld cellworld }'
> In a stmt of a 'do' expression:
> onClicked setWorldSize
> $ do { canvas <- xmlGetWidget xml castToDrawingArea "world";
> let size = (read (get sizeBox entryText) :: Int);
> cellworld <- makeWorld size;
> printWorld cellworld }
makeWorld size, on the other hand is not an IO-action but a list (of
(Int,Int) pairs), so you can't use "<-" to bind it to a name in an IO-
block, here you must use let:
let cellworld = makeWorld size
print cellWorld
>
> It seems to be complaining about the call to my makeWorld function,
> although I do not understand why that should be. The line number
> which GHC complains about does correspond to the "cellworld <-
> makeWorld size" line in my main function.
>
> I've not yet worked out how to draw my world in the GUI, the
> "printWorld" function mentioned above just spills the world out to the
> termainal for now.
>
> Does anyone have any ideas?
>
> Many thanks,
>
> Tom
More information about the Beginners
mailing list