我正在使用 UI 制作应用程序,我需要通过 IO
运行 StateT
和 ReaderT
中的代码,我我正在使用 Graphics.UI.Gtk
作为 UI,但遇到以下问题:
我需要当单击某个按钮时它会调用具有签名的函数
tryAttack :: Int -> ReaderT Builder (StateT BattleState IO) Bool
但在 GTK
中,在 clickedOn
函数上它需要一个 IO ()
参数:
onClicked :: ButtonClass b => b -> IO () -> IO (ConnectId b)
如何让这个 clickedOn
函数“愚弄”它,使其认为 tryAttack
是 IO ()
。
attackButton builder leftTR i = do
moveButton <- builderGetObject builder castToButton ("move" ++ show i)
onClicked moveButton $ do
ok <- tryAttack i
if ok
then hideAndShow builder castToTable "fight" "option"
else return ()
tryAttack :: Int -> ReaderT Builder (StateT BattleState IO) Bool
tryAttack i = return True
显然 tryAttack
代码是临时的。
最佳答案
您需要解开 reader monad,然后声明 monad 以获得 bool 结果:
(ok,newBattleState) <- runStateT (runReaderT (tryAttack i) builder) battleState
关于Haskell GTK 和 Monad 变压器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17736560/