Haskell: разделить список, используя понимание списка
Как разделить список на две части, используя понимание списка?
например, если у меня есть [1,1,2,2,3,3,4,4,5,5]
и я хочу только [1,1,2,2,3]
мои попытки пока:
half mylist = [r | mylist!r ; r <- [0..(#mylist div 2)] ] ||does not work
Какие-нибудь мысли?
[Nb: На самом деле это не Хаскелл, а похоже.! используется для индексации списка, а # дает длину)
Редактировать::
Хорошо, так получается, что
half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]
работает, но только в списке чисел, а не строк. Есть какие-нибудь подсказки?
2 ответа
Это не совсем уместно для понимания списка. Понимания списка - это альтернативный синтаксис для карт и фильтров (и почтовых индексов). Разделение списка - это сгиб.
Таким образом, вы должны рассмотреть другой подход. Например
halve :: [a] -> [a]
halve [] = []
halve xs = take (n `div` 2) xs
where n = length xs
Разделение не является хорошей операцией для больших списков, так как вы сначала берете длину (так что это всегда n + n / 2 операций над списком. Это больше подходит для массивоподобных типов, которые имеют длину O(1) и разделение,
Еще одно возможное решение с использованием логической защиты:
half xs = [x | (x,i) <- zip xs [1..], let m = length xs `div` 2, i <= m]
Но, как говорит Дон Стюарт, составление списков не совсем подходящий инструмент для этой работы.