2012-01-23 3 views
2

Почему эти следующие функции не работают одинаково? Первый один делает правильную строку раскол, но второй один, кажется, продолжает добавлять «» навсегда, создавая бесконечный списокПочему эти 2 части кода не ведут себя одинаково?

Правильный код:

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 Код:

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 

только часть, которая отличается, является условием перерыва, и мне кажется, что она должна делать то же самое ... плюс первая форма функции должна гарантировать, что я не буду добавлять пустые списки к моему результату навсегда ... Извините за noobish вопрос и спасибо заранее

ответ

6
GOA> break (=='c') "abcde" 
("ab","cde") 
GOA> break (=='c') "cde" 
("","cde") 
GOA> 

break не снимает символ, который соответствует ему.

3
break p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs) 

В вашей первой версии, которая работает, вы применяете tail к результату dropWhile.

В вашей второй версии, которая не работает, вы этого не сделаете.

2

Как объяснили другие, break возвращает пару takeWhile и dropWhile. Вы хотите взять хвост dropWhile. Вы можете сделать это следующим образом:

where 
(isMatch,_:rest)=break (==y) lista 
Смежные вопросы