Haskell — Popping from a list in state while a condition is true
Haskell — Popping from a list in state while a condition is true
I'm dealing with data that stores its state as a String
, treating the string like a stack. I also have to combine that with error handling.
To that end, I'm using the type StateT String Maybe a
. I have a function to pop and to push a Char
from and to the string:
pop :: StateT String Maybe Char
pop = do
x:xs <- get
put xs
return x
push :: Char -> StateT String Maybe ()
push x = do
xs <- get
put (x:xs)
return ()
I wrote a function to repeatedly pop
from the string while the characters being popped fulfilled a condition. It behaves as follows:
> runStateT (popWhile (<'a')) "HELLO world"
Just ("HELLO ","world")
> runStateT (popWhile (>'a')) "HELLO world"
Just ("","HELLO world")
My implementation is the following:
popWhile :: (Char -> Bool) -> StateT String Maybe [Char]
popWhile f = do
s <- get
if null s
then return []
else popAgain
where
popAgain = do
x <- pop
if f x
then liftM (x:) (popWhile f)
else push x >> return []
But that seems pretty bulky, and has two if then else
's in it. Is there a better way to write this function?