سؤال

I'm making and application with UI and I need to run code that is in a StateT and a ReaderT over IO, I'm using Graphics.UI.Gtk for the UI and I have the following problem:

I need that when a certain button is clicked it calls a function that has signature

tryAttack :: Int -> ReaderT Builder (StateT BattleState IO) Bool

but in GTK, on the clickedOn function it takes an IO () argument:

onClicked :: ButtonClass b => b -> IO () -> IO (ConnectId b)

How can I make "fool" this clickedOn function to think that tryAttack is 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

obviously the tryAttack code is temporary.

هل كانت مفيدة؟

المحلول

You need to unwrap the reader monad and then state monad to get the bool result:

(ok,newBattleState) <- runStateT (runReaderT (tryAttack i) builder) battleState
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top