omu_negru
omu_negru

Reputation: 4770

Why do these 2 pieces of code not behave identically?

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

Answers (3)

newacct
newacct

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

dave4420
dave4420

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

ben w
ben w

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

Related Questions