Is it bad to have splitInternal function? I couldn't figure out a way without it.
Well, according to your procedure, I think it is necessary, but you can improve the readibility by writing some small functions and then combining them together. Besides, if there are consecutive delimiters, your split
function doesn't work as expected. The code can be rewritten as following:
splitInternal :: Char -> ([String], String) -> ([String], String)
splitInternal _ (result, "") = (result, "")
splitInternal c (result, remain) = splitInternal c (getBefore c remain, getAfter c remain)
where
getBefore delimiter rest = result ++ [takeWhile (/= delimiter) rest]
getAfter delimiter rest = dropWhile (== delimiter) . dropWhile (/= delimiter) $ rest
Is there maybe a simpler way to write the function?
Yes, you can use the break
and span
function defined in Prelude
:
split :: Char -> String -> [String]
split _ "" = []
split delimiter str =
let (start, rest) = break (== delimiter) str
(_, remain) = span (== delimiter) rest
in start : split delimiter remain
So in this case, your splitInternal
is unnecessary.
Any other feedback is welcome as well
Well, if you are dealing with string, then a better choice is Text
from Data.Text
. Text
is more efficient than String
when you are dealing with string. In the module Data.Text
, there is a pre-defined function splitOn
that works almost as you expect:
ghci> :seti -XOverloadedString
ghci> splitOn "," "123,456,789"
["123","456","789"]
ghci> splitOn "," "123,,,456,789"
["123","","","456","789"] -- This is what I mean "almost", since splitOn doesn't use the consecutive delimiters. Maybe this is what you want.
```