smilingbuddha
smilingbuddha

Reputation: 14660

How to print to the terminal in this Haskell code?

I am trying to get a simulation running with Gloss in Haskell.

I tried writing a simple script where I want to print "Clicked!" to the terminal every time I click anywhere on the Gloss canvas. The world I pass to the Gloss' play function, is an IO action so I can enable printing to the terminal in response to events.

However, nothing prints to the terminal! :-(

module Main where
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
import System.IO.Unsafe

data World  = World { test :: String
                   } deriving (Show)

main :: IO ()
main = do
          let initialioWorld   = return World{test=""} :: IO World
          let windowSize      = (1800,1800)
          let windowPosition  = (0,0)
          let backgroundColor = orange
          let framesPerSecond = 20
          play (InWindow "" windowSize windowPosition) backgroundColor framesPerSecond
                initialioWorld ( const Blank ) handleEvent  (const id)


handleEvent :: Event -> IO World  -> IO World
handleEvent event ioworld

 | (EventKey (MouseButton LeftButton) Down _ (x,y)) <- event,
               World str <- unsafePerformIO ioworld
   = do
       putStrLn "Clicked!"
       return (World str)

 | otherwise = ioworld

Now I understand, what Haskell is probably doing is just evaluating that IO action and NOT executing it, and that this has something to do with Haskell's laziness.

So how do I force printing to the terminal in this case?

Upvotes: 2

Views: 686

Answers (1)

pat
pat

Reputation: 12749

You are using the pure version of play. If you want to do IO in the event handler, you must use Graphics.Gloss.Interface.IO.Game.playIO. With that, the event handler has type

Event -> world -> IO world

Which takes a pure world, and returns an IO action that will be executed.

Note that this will also require your drawing and step functions to return IO actions as well ((return . const Blank), and (return . const id) respectively). Also, you must no longer return your initial world into IO.

Upvotes: 3

Related Questions