You need to unwrap the reader monad and then state monad to get the bool result:
(ok,newBattleState) <- runStateT (runReaderT (tryAttack i) builder) battleState
سؤال
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