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]

Но, как говорит Дон Стюарт, составление списков не совсем подходящий инструмент для этой работы.

Другие вопросы по тегам