Here's my version:
import Control.Monad
import Control.Monad.State
-- filter `str` with the "stateful" monadic predicate function `handleChar`,
-- with an initial state of 0
getRidOfArguments :: String -> String
getRidOfArguments str = filterM handleChar str `evalState` 0
handleChar :: Char -> State Int Bool
handleChar '(' = modify (+1) >> gets (<= 1)
handleChar ')' = modify (max 0 . subtract 1) >> gets (== 0)
handleChar _ = gets (== 0)
My thought process was: we're filtering a list so filter
comes to mind; however whether we keep or drop a character depends on some state (our count of open/closed parens). So the monadic filter function filterM
is appropriate, and we can use the State
monad to abstract that plumbing of our open/close count.
Let me know if you want more details on how the above works.