Почему эти 2 фрагмента кода не ведут себя одинаково? - PullRequest
2 голосов
/ 23 января 2012

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

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

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

Неверный код:

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

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

Ответы [ 3 ]

6 голосов
/ 23 января 2012
GOA> break (=='c') "abcde"
("ab","cde")
GOA> break (=='c') "cde"
("","cde")
GOA> 

break не удаляет совпадающий символ.

3 голосов
/ 23 января 2012
break p xs = (takeWhile (not . p) xs, dropWhile (not . p) xs)

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

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

2 голосов
/ 24 января 2012

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

where 
(isMatch,_:rest)=break (==y) lista
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...