1
split sep str = foldr op [[]] str
    where op (x:xs) (y:ys)
              | x == sep = ([]:y)
              | otherwise = ((x:y):ys)

I'm trying to make a string split starting from a string and getting to a list of strings. What is wrong with this code?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555

1 Answers1

1

([]:y) makes no sense, since it should be a list of lists of items, but y is a list of items. Even if the type system would not complain (for example because of a dynamically typed language like Python), it would not make much sense, since you drop ys, which would thus omit the rest of the recursion.

Another problem is that you write (x:xs) as first parameter, which means that the items in the list you fold are lists themselves, but given I understand it correctly, you fold a String, so the element is simple character:

You can fix this by returning []:y:ys:

split :: (Foldable f, Eq a) => a -> f a -> [[a]]
split sep str = foldr op [[]] str
    where op x ~(y:ys)
              | x == sep = []:y:ys
              | otherwise = (x:y):ys

For example:

Prelude> split '-' "this-is-kebab-case"
["this","is","kebab","case"]
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 2
    Obviously this question reminds the `words` function. One thing worth noting with the `words` function is `words " "` resulting `[]`. So coming back to this topic; what if the string only consists of separators? Such as `"------"` in your test case. While your answer being sufficient for the OP's problem, still It could be a good idea to check [words](https://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.OldList.html#words) definition :) – Redu Apr 13 '20 at 18:19