How to implement the inverse of "intercalate" (splitting a string into pieces on a character) using functions from "base"?

Viewed 899

I wanted to split a string on newlines and I was surprised that I could not find the inverse function to intercalate "\n". That is, a function that splits a string into pieces on new lines (or according to some other predicate).

Note that lines and words do something different. For example

intercalate "\n" (lines "a\n") == "a"

There is a similar function function splitOn in the split library. I could also write such a function myself directly:

splitOn :: (a -> Bool) -> [a] -> [[a]]
splitOn p = map reverse . g []
  where
    g rs []                 = [rs]
    g rs (x:xs) | p x       = rs : g [] xs
                | otherwise = g (x : rs) xs

but I wonder if it could be constructed more easily using only functions from base.

2 Answers
Related