Haskell:使用list comprehension拆分列表

时间:2012-05-05 17:43:41

标签: haskell split list-comprehension miranda

如何使用列表推导将列表拆分为两半?

e.g。如果我有[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)] ]

有效,但仅限于数字列表而非字符串。有线索吗?

2 个答案:

答案 0 :(得分:8)

这与列表理解不太合适。列表推导是地图和过滤器(和拉链)的替代语法。拆分列表是一种折叠。

因此,您应该考虑采用不同的方法。 E.g。

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

拆分对于大型列表来说不是一个很好的操作,因为你先取长度(所以它总是 n + n / 2 操作列表。)更适合具有 O(1)长度和拆分的类似数组的类型。

答案 1 :(得分:4)

另一种可能的解决方案,使用布尔守卫:

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

但正如Don Stewart所说,列表理解并不是这项工作的正确工具。