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: На самом деле это не Haskell, но похоже. ! используется для списка индексации, а # дает длину)

Редактировать::

Ладно получается, что

half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]

работает, но только в списке чисел, а не строк. Какие-нибудь подсказки?


person tetris11    schedule 05.05.2012    source источник


Ответы (2)


Это не совсем подходящая вещь для понимания списка. Понимание списков - это альтернативный синтаксис для карт и фильтров (и zip-архивов). Разделение списка складывается.

Таким образом, вам следует рассмотреть другой подход. Например.

halve :: [a] -> [a]
halve [] = []
halve xs = take (n `div` 2) xs
    where n = length xs

Разделение - не самая лучшая операция для больших списков, поскольку вы сначала берете длину (так что в списке всегда n + n / 2 операций. Это более уместно для типов, подобных массиву, имеющих длину O (1) и разделение.

person Don Stewart    schedule 05.05.2012
comment
Цените ответ, но это просто не сработает в Миранде. Нет функции splitAt ... - person tetris11; 05.05.2012
comment
Могу я просто указать, что Миранда - мертвый язык. Тем не менее, вы все равно можете реализовать splitAt самостоятельно, как splitAt n xs = (take n xs, drop n xs) - и мы должны просто использовать take :) - person Don Stewart; 05.05.2012
comment
Поверь мне, я полностью осознаю, насколько мертва Миранда. К сожалению, мой лектор написал об этом учебник, и поэтому мы вынуждены его выучить. Хотя это довольно весело. - person tetris11; 06.05.2012
comment
'брать'! Вау, я полностью пропустил эту функцию. Да, это решает проблемы безмерно --- спасибо! - person tetris11; 06.05.2012

Другое возможное решение с использованием логической защиты:

half xs = [x | (x,i) <- zip xs [1..], let m = length xs `div` 2, i <= m]

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

person Chris Rice    schedule 05.05.2012
comment
Сначала это удивительно, но это примерно так же эффективно, как предложение Дона или более очевидное take n mylist where n = length mylist `div` 2 Не знаю, что будет делать реализация Miranda. - person applicative; 05.05.2012