Haskell: Split a list using list comprehension
-
06-06-2021 - |
سؤال
How do you split a list into halves using list comprehension?
e.g. If I have [1,1,2,2,3,3,4,4,5,5]
and I only want [1,1,2,2,3]
my attempts so far:
half mylist = [r | mylist!r ; r <- [0..(#mylist div 2)] ] ||does not work
Any thoughts?
[Nb: This isn't actually Haskell but similar. ! is used for indexing list, and # gives length)
Edit::
Okay so it turns out that
half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]
works, but only in list of numbers and not strings. Any clues?
المحلول
This isn't really an appropriate thing to do with a list comprehension. List comprehensions are alternate syntax for maps and filters (and zips). Splitting a list is a fold.
As such, you should consider a different approach. E.g.
halve :: [a] -> [a]
halve [] = []
halve xs = take (n `div` 2) xs
where n = length xs
Splitting isn't a great operation on large lists, since you take the length first (so it is always n + n/2 operations on the list. It is more appropriate for array-like types that have O(1) length and split.
نصائح أخرى
Another possible solution, using a boolean guard:
half xs = [x | (x,i) <- zip xs [1..], let m = length xs `div` 2, i <= m]
But as Don Stewart says, a list comprehension is not really the right tool for this job.