Reputation: 35
I have a given char or num, and I want to split a list at the same characters or numbers.
split a "heyahelloaeveryone" == "hey,hello,everyone "
the type should be : Eq a => a -> [a]
split _ [] = []
split c (x:xs)
| c == x = [[]] ++ split c xs
| otherwise = (x : head(split c xs)) : tail(split c xs)
I've tried with this, but this code doesn't work for these situations: split a [a] == [[],[]] split a [] == []
Upvotes: 1
Views: 116
Reputation: 3479
You can initialize your list with the first element as an empty list. This way you start correctly with the type (list of lists) you want to have.
However, the resulting type is split :: Eq a => a -> [a] -> [[a]]
split _ [] = [[]]
split c (x:xs)
| c == x = [[]] ++ split c xs
| otherwise = (x : head(split c xs)) : tail(split c xs)
Upvotes: 1
Reputation: 476557
For an empty list, you will need to return a singleton list as well. This of course then conflicts with split a [] == []
, but we can first perform a check, and only if the given list is not empty, perform a recursive algorithm:
split :: Eq a => a -> [a] -> [[a]]
split _ [] = [] -- ← empty list for an empty list
split c ls = go ls
where go [] = [[]] -- ← single empty list for an empty list
go (x:xs) | c == x = [] : go xs
| otherwise = (x:y) : ys
where ~(y: ys) = go xs
This gives us the expected value for split 'a' "a"
:
Prelude> split 'a' ""
[]
Prelude> split 'a' "a"
["",""]
Prelude> split 'a' "foobar"
["foob","r"]
Prelude> split 'a' "foobarqux"
["foob","rqux"]
Prelude> split 'a' "foobaarqux"
["foob","","rqux"]
Upvotes: 0