2012-05-05 8 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 

任意の考えを?

[Nb:これは実際にはハスケルではありませんが、これに似ています。 !インデックスリストのために使用され、#は、長さを与える)

編集さ::

オーケー、それはその

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

作品が判明ので、しかし、数字だけではなく文字列のリストインチすべての手がかりは?

答えて

8

これは本当にリストの理解とは関係ないことです。リスト内包表記は、マップとフィルタ(およびzip)の代替構文です。リストを分割するのは簡単です。

このように、異なるアプローチを検討する必要があります。例えば。

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

あなたが第1の長さを取る(それは、リスト上のn + N/2操作常にあるので、分割は、大規模なリストに多大な操作ではありません。それはarray-ためのより適切です

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

しかしドンStewaとして:ブールガードを使用して、O(1)長さと分割

+0

答えは分かりますが、これはミランダではうまくいきません。 splitAt関数はありません... – tetris11

+0

ミランダは死んだ言語であることを指摘できますか?それにもかかわらず、 'splitAt n xs =(take n xs、drop n xs)'と同じように 'splitAt'を自分で実装することができます - とにかく' take'を使うべきです:) –

+0

私は完全に認識しています死んだミランダはどれぐらいですか?残念なことに私の講師は教科書を書いているので、それを学ばなければなりません。しかし、それはかなり楽しいです。 – tetris11

4

別の可能な解決策を持っているタイプのようなrtは、リストの理解は本当にこの仕事のための正しいツールではないと言います。

+0

ブーム。パーフェクト、ちょうど私が感謝のために探していたもの。 – tetris11

+0

これは最初は驚くべきことですが、これはdonsの提案やより明白な 'take n mylistと同じくらい効率的です。ここで、n =長さmylist \' div \ '2'DunnoはMirandaの実装で何をしますか? – applicative

関連する問題