2012-05-05 76 views
1

如何使用列表理解將列表拆分爲兩半?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 

有什麼想法?

[鈮:這實際上不是Haskell,但類似。 !被用於索引列表,並給出了#長度)

編輯::

好了,事實證明,

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

作品,但只有在數字,而不是字符串列表。任何線索?

回答

8

這對於列表理解並不合適。列表解析是映射和過濾器(和拉鍊)的替代語法。分割列表是一個摺疊。

因此,您應該考慮一種不同的方法。例如。

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

分裂不在大名單有很大的操作,因爲你先取長度(所以它總是在名單上ň + N/2操作。它是更適合於基於陣列像

+0

欣賞答案,但這只是在米蘭達不會工作。沒有splitAt功能... – tetris11

+0

我能指出米蘭達是一種死去的語言嗎?儘管如此,你仍然可以自己實現'splitAt',因爲'splitAt n xs =(拿n xs,drop n xs)' - 我們應該只用'take' :) –

+0

哈哈相信我我完全知道米蘭達是如何死去的。不幸的是,我的講師在其上寫了教科書,因此我們不得不學習它。雖然這很有趣。 – tetris11

4

另一種可能的解決方案,使用一個布爾後衛具有O(1)長度和拆分類型:

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

但作爲唐Stewa。 rt說,列表理解不是真正適合這份工作的正確工具。

+0

繁榮。完美,正是我在尋找的感謝。 – tetris11

+0

這首先令人感到驚訝,但這與dons的建議或更明顯的「採取mylist,其中n =長度mylist \ div \'2」一樣有效。不知道米蘭達實施會做什麼。 – applicative