variables - 如何使用 IO 和 GTK 更新 main 中的“变量”
问题描述
我对 Haskell 还很陌生,所以请原谅我天真的方法。我试图在 GTK (gtk2hs) 的主循环中使用“全局变量”来保存/编辑我正在尝试编程的游戏的状态,以及表示当前是否正在玩游戏的 Bool。
我目前的方法是为两者定义数据类型,如下所示:
data GameBool = GameBool { gameBoolvalue :: Bool } deriving (Show)
main :: IO ()
main = do
initGUI -- inits GTK
-- do GUI stuff
gameBool <- initGameBool
on button buttonActivated $ callbackNewGame gameBool
mainGUI -- runs GTK loop
initGameBool = do
return $ GameBool False
callbackNewGame :: GameBool -> IO ()
callbackNewGame gameBool = do
-- Do stuff to check if a game is running in if then else etc.
updateGameBool gameBool True
putStrLn "New Game Started" -- This is not what i do, but represents it well
updateGameBool gameBool b = do
return $ gameBool { gameBoolvalue = b}
不过,这不会更新我的 gameBoolvalue,它保持为 False。
我尝试了 Control.Lens 而不是记录语法(updateGameBool 函数),但这只会以我不理解的可怕崩溃告终。(是的,我将 TemplateHaskell 添加到 LANGUAGE 并执行 makeLenses ''GameBool)这个:
set gameBoolvalue True gameBool
结果是:
error:
couldn't match type 'Bool'
with 'GameBool -> Identity (IO a0)'
Expected type: ASetter GameBool (IO a0) a1 Bool
Actual type: GameBool -> Bool
In the first argument of 'set', namely 'gameBoolvalue'
In a stmt of a 'do' block: set gameBoolvalue True gameBool
我了解我的实际类型,但不是它想要告诉我的预期类型,因为它不遵循 set AT ALL 的 API,也不是类型。
我怀疑我误解了 do 块/其中变量的交互/声明。是的,我知道它们并不是真正的变量,如果可以的话,我会使用一个简单地将当前值传递给下一次迭代的循环,但 GTK 让我无法做到。我只想更新布尔(和我的游戏状态,但我认为那是同样的错误)。
任何帮助,将不胜感激!
解决方案
推荐阅读
- java - 如何以编程方式加载 JDK 模块?
- python - 将美元转换为日元的 Python 编码失败
- android - 有没有办法在不停止播放的情况下以编程方式执行 YouTube 全屏操作?
- asp.net-core - 如何添加 Swashbuckle AspNetCore XmlCommentsDocumentFilter
- sails.js - Sails:如何在sails v1.0 中为一对一关联插入数据?
- python - 将导入的python模块提取到文件中?
- flutter - 无法运行颤振演示应用程序给出错误
- mongodb - AWS S3 与 MongoDB
- c# - 我可以使用自定义属性创建 XmlAttributeOverrides 吗?
- swift - PHAssetChangeRequest 以低分辨率保存