2016-10-08 2 views
2

Я пытаюсь получить симуляцию с Gloss в Haskell.Как распечатать на терминал в этом коде Haskell?

Я пробовал написать простой скрипт, где я хочу напечатать «Clicked!» на терминал каждый раз, когда я нажимаю на холст Gloss. Мир, который я перехожу к функции воспроизведения Глосса, является действием ввода-вывода, поэтому я могу включить печать на терминал в ответ на события.

Однако ничего не распечатывается на терминале! :-(

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 

Теперь я понимаю, что Haskell, вероятно, делает это только оценки что действия IO и НЕ выполняющийся, и что это что-то делать с ленью Хаскеля.

Так как я заставляю печать на терминал в этом случае?

ответ

3

вы используете чистую версию play. Если вы хотите сделать IO в обработчик события, вы должны использовать Graphics.Gloss.Interface.IO.Game.playIO. при том, что обработчик событий имеет тип

Event -> world -> IO world 

Который берет чистый world и возвращает IO действие, которое будет выполняться.

Обратите внимание, что это также потребует, чтобы ваши функции рисования и шага возвращали IO действия ((return . const Blank) и (return . const id) соответственно). Кроме того, вы не должны больше return вашего начального мира в IO.

+0

О, ничего себе! Это сработало отлично. Спасибо огромное! Чтобы быть уверенным, я могу делать произвольные функции ввода-вывода с этой функцией правильно, я пишу/читаю из файлов и т. Д. Я имею в виду, что мы не ограничиваемся печатью на терминале? – smilingbuddha

+0

@smilingbuddha Вы * можете *, но помните, что у вас мало контроля над тем, как вызывается функция обратного вызова. Если вам действительно нужно управлять реальными ресурсами внутри вашей игры (а не только печатью на stdout), вы должны сделать это в потоке, запущенном за пределами глянцевой версии. – user2407038

Смежные вопросы