I know this is an old post, but I saw no solutions that implemented good old fold
.
First strip the leading white-space using dropWhile
. Then, using foldl'
and a simple closure, you can analyze the rest of the string in one pass, and based on that analysis, pass that informative parameter to take
, without needing reverse
:
import Data.Char (isSpace)
import Data.List (foldl')
trim :: String -> String
trim s = let
s' = dropWhile isSpace s
trim' = foldl'
(\(c,w) x -> if isSpace x then (c,w+1)
else (c+w+1,0)) (0,0) s'
in
take (fst trim') s'
Variable c
keeps track of combined white and non white-space that should be absorbed, and variable w
keeps track of right side white-space to be stripped.
Test Runs:
print $ trim " a b c "
print $ trim " ab c "
print $ trim " abc "
print $ trim "abc"
print $ trim "a bc "
Output:
"a b c"
"ab c"
"abc"
"abc"
"a bc"