Haskell leave monad state early (guard?)

I have a type representing the state of the game for my application, as this question pretends to be something simple:

Game { points :: Int }

I define my logic of the game with the state monad.

type GameState a = StateT Game a

addPoints :: Int -> GameState ()
addPoints num = do
    Game p <- get
    put $ Game (p+num)

I want to be able to simply discard some inputs

evenResult num = do
    Game p <- get
    return $ even (p + num) 

addPoints num = do
    isEven <- evenResult num
    if isEven then return () else do
    Game n <- get
    put $ Game (n+num)

I need a syntax that looks something like this:

addPoints num = do
    guard evenResult
    ...

-- or this
addPoints num = do
    guardIsEvenResult
    ...

If he is on guard, I want him to leave the state alone and not do anything in the block .

How can i do this? It seems to me that it is possible with MonadPlus, but I'm not sure I can use mzero to say "return what you already have in your state." Thank!

+3
source share
2 answers

Control.Monad.Trans.Maybe MaybeT StateT. mzero, , , guard condition , condition False; , , - runMaybeT. ( , lift , StateT, , operation :: (MonadState m Game) => ....)

, , , transformers, Control.Monad.Trans.Maybe, ; mtl, , Control.Monad.State, .

+6

, .

ensure :: GameState Bool -> GameState () -> GameState ()
ensure p k = do 
  t <- p 
  when t k

addPoints num = do
  ensure (evenResult num) $ do
  ...

. , , , . :)

0

All Articles