Reputation: 4770
Why do these following functions not work the same ? The first one is doing a proper string split but the second one seems to keep adding "" forever, creating an infinite list
Right code:
my_split :: [Char]->Char->[[Char]]
my_split [] _ = [[]]
my_split lista y
| notElem y lista=[lista]
| otherwise=isMatch:(my_split rest y)
where
isMatch=takeWhile (/=y) lista
rest=tail $ dropWhile (/=y) lista
Bad Code :
my_split :: [Char]->Char->[[Char]]
my_split [] _ = [[]]
my_split lista y
| notElem y lista=[lista]
| otherwise=isMatch:(my_split rest y)
where
(isMatch,rest)=break (==y) lista
The only part that's different is the break condition and it really seems to me it should do the same thing...plus the first function form should ensure i don't get to add empty lists to my result forever...Sorry about the noobish question and thanks in advance
Upvotes: 2
Views: 165
Reputation: 122518
As others have explained, break returns the pair of takeWhile and dropWhile. You want to take the tail of the dropWhile. You can do it like this:
where
(isMatch,_:rest)=break (==y) lista
Upvotes: 2
Reputation: 47072
break p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs)
In your first version that works, you apply tail
to the result of dropWhile
.
In your second version that doesn't work, you don't do this.
Upvotes: 3
Reputation: 2535
GOA> break (=='c') "abcde"
("ab","cde")
GOA> break (=='c') "cde"
("","cde")
GOA>
break
doesn't strip off the character it matches.
Upvotes: 6