2017-03-24 10 views
0

私のコードでは望みの結果が得られますが、これをコード化する良い方法があるのだろうかと思います。haskell最適化無限リストコード

pair [ 1 , 2 , 3 , 4 , 5 , 6 , ... ] 
[ [ 1 , 2 ] , [ 3 , 4 ] , [ 5 , 6 ] , ... ] 

と与えられたコード:

pair::[a] -> [[a]] 
pair = 

私のソリューション:

pair :: [a] -> [[a]] 
pair (x:y:xs) = ((x:y:[]):[]) ++ pair xs 
+0

':': '++'は* O(n)*(* n *は最初のリストのサイズ)で動作しますが、 ':'は* O 。 –

+3

@WillemVanOnsemもしあなたが '(++)'を '(:)'に置き換えることができたとしても、最初のリストのサイズが* O(1)*ならば、 '(++)'も* O (1)*。だから、 '(:)'は '(++)'より恒常的に速い定数であるかもしれませんが、漸近的には同じです。 – jpath

+0

あなたは質問を述べなかった。 –

答えて

1

はるかにパフォーマンス連結リストよりもなり短所演算子:を使用する:これは与えられた例である

pair :: [a] -> [[a]] 
pair (x:y:xs) = [x, y] : pair xs 

Haskellのリストは、リンクされたリストであり、各項目はリストの最後までポイントします。プッシュとポップは、既存のリストの先頭に頭を向けているだけなので、リストの先頭で完了すると安いです。

2つのリンクされたリストを連結すると、最後の要素が2番目のリストの最初の要素を指すことができるように、完全な最初のリストが基本的に再構築されます。

リストに2つの要素しかないので、パフォーマンスの向上はわずかですが、一般的なルールとして、リストの先頭の操作を処理する場合は、ほとんど常にパフォーマンスが向上します短所を使う

+0

ありがとうございます! – Lorenzo

+1

このアサーションをテストしましたか?私のテストでは、GHCは両方の実装で全く同じコアを出しています。 –

+0

コンパイル済みのGHCはテストしていません。この具体的なケースで最適化できるのであれば、それはかなり涼しく、私は答えを更新することができますが、一般的なルールが成り立つと思います。 ':'で十分で、少なくとも理論的には '++ ' 、より多くの演奏者。 –