I recently made a small algorithm to strip out function arguments from a snippet of code and only keep the outermost functions.
I found that this algorithm was very easy to design in an imperative way.
However, I'm really interested in functional programming and I was wondering how you would accomplish the same thing in a functional way.
It would be very helpful to me if you could show me how such an algorithm might work, so I might get a better idea of how functional programming works. Also I'd like to know what your thought process is while designing the algorithm.
I made the imperative version in Python, but your answer doesn't have to be in python; haskell or any other language will do just as well.
Here's what it does (taking a string as input and returning a string):
"foo(a.d, b.e.fi()).go(sd, ds())" -- returns --> "foo().go()"
"foo(a, b).bar().fuu" -- returns --> "foo().bar().fuu"
"foo.bar" -- returns --> "foo.bar"
And here's my imperative code:
def get_rid_of_arguments(text):
i, start, end = 0, 0, 0
result = ""
for j, c in enumerate(text):
if c == '(':
if i == 0:
start = j
result += text[end:start]
i += 1
elif c == ')':
i -= 1
if i == 0:
end = j + 1
result += '()'
return result + text[end:]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With