Определение группы Haskell с функцией span - PullRequest
0 голосов
/ 15 ноября 2018

Мне нужно определить групповую функцию - Haskell, но я просто могу сделать это с помощью takeWhile и dropWhile, но я не могу сделать это с помощью span.И мне нужно сделать это с пролетом!Не могли бы вы помочь мне?Вот мой код с tW и dW:

group' :: (Eq a) => [a] -> [[a]]
group' [] = []
group' (x:xs) = (x : takeWhile (== x) xs) : group' (dropWhile (== x) xs)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Глядя на определение span в hackage , мы находим этот полезный совет:

span p xs эквивалентно (takeWhile p xs, dropWhile p xs)

Итак, как вы определили свою функцию как

group' [] = []
group' (x:xs) = (x : takeWhile (==  x) xs) : group' (dropWhile (== x) xs) 

Вы можете легко увидеть, что ваш p в этом случае (== x). Итак, заменив его в определении диапазона выше

span p xs = (takeWhile p xs, dropWhile p xs)
span (== x) xs = (takeWhile (== x) xs, dropWhile (== x) xs)

span возвращает пару списков, поэтому вы можете получить к ним доступ с помощью fst и snd. Итак, у нас есть это

takeWhile (== x) xs = fst (span (== x) xs) 

и

dropWhile (== x) xs = snd (span (== x) xs) 

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

group' [] = []    
group' (x:xs) = (x : fst (span (== x) xs) ) : group' (snd (span (== x) xs) ) 

Конечно, нехорошо вызывать одну и ту же функцию с одинаковыми аргументами дважды (span (== x) xs), поэтому давайте вызовем ее всего один раз с привязкой let:

group' [] = []
group' (x:xs) = let s = span (== x) xs in (x : (fst s)) : group' (snd s)

Мне нравится, что Haskell в конце концов просто математика, и вы можете заменить некоторые определения (например, те, которые вы использовали с takeWhile и dropWhile) другими (span), используя только некоторые алгебраические уравнения!

0 голосов
/ 15 ноября 2018

Попробуй это.

 group' (x:xs) = a:(group' b) where (a,b) = span (==x) (x:xs)

Span просто возвращает два списка, которые разделены с помощью данной функции.

...