Skip to main content
Code Review

Return to Question

Tweeted twitter.com/#!/StackCodeReview/status/559402164788162560
edited tags
Link
200_success
  • 145.5k
  • 22
  • 190
  • 478
Remove tag text from title.
Link
Brythan
  • 7k
  • 3
  • 21
  • 37

Haskell — Popping from a list in state while a condition is true

Source Link
Matthew
  • 153
  • 4

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?

lang-hs

AltStyle によって変換されたページ (->オリジナル) /