2011-11-01 13 views
6

Tek bir ifadede 3 liste veya daha fazlasını bir kerede eklemek istiyorum.++'nin çoklu kullanımı: değerlendirmeyi sağdan sola zorlarsam daha verimli olur mu?

a ++ b ++ c 

++ operatörü soldan sağa veya sağdan sola değerlendirilecek mi? ++ bir önek işlevi olsaydı, biz doğal olarak ilk ++ b c değerlendirerek yol açan ++ a ++ b c yazardı çünkü

1. (a ++ b) ++ c 
2. a ++ (b ++ c) 

Ben 2. seçeneği söyleyebilirim. Doğru olup olmadığından emin değilim.

Ama seçenek 1 ise, o explicitely sağdan değerlendirme sırasını değiştirerek sola geliyor bana daha verimlidir:

İşte
a ++ (b ++ c) 

neden: a ++ b ++ c ilk (n adımlarla ab ++ c değerlendirecek n ve a'nın uzunluğu ise, a ve b) 'nin ve daha sonra abc'un n + m daha fazla adımda birleştirilmesidir (m, b'nin uzunluğu, böylece n + m, ab uzunluğudur), toplam 2n + m adımlar yapar. Oysa, a ++ (b ++ c), önce m adımlarında a ++ bc ve sonra da daha fazla adımda abc değerini değerlendirecektir, ki bu toplamda sadece n + m adımlarıdır.

Haskell'e yeniyim ve söylediklerim konusunda emin değilim, biraz onay istiyorum. ghci itibaren

cevap

11
a ++ b ++ c 

açıkladığınız tam nedenlerle

a ++ (b ++ c) 

olarak ayrıştırılır: (++) olmuştur sola ilişkilendirilebilir vardı, sonra a ++ b ++ c iki kez a kopyalamak olacaktır. Sen infixr "infix sağ ilişkilendirilebilir" anlamına

infixr 5 ++ 

ile yanıt verirken

Prelude> :i (++) 

ile GHCi bu kontrol edebilirsiniz.

6

, do :i: ++ (infix ve) sağ ilişkisel ve sağdan sola değerlendirilecektir göstermektedir

Prelude> :i (++) 
(++) :: [a] -> [a] -> [a] -- Defined in GHC.Base 
infixr 5 ++ 

. Bilmiyorum, ama doğru-ilişkisel hale getirdiğinde, aklınıza gelen her şeyi aklınızdan çıkarmayınca bahse girerim.

+2

Ve bu infixr parantez olmadan, seçenek 2. –

+0

Ben açıkça vurgulanmıştır herhalde demektir! –

+2

Evet, ++ 'nın ilişkilendirilmesi onu daha verimli hale getirmek için tam olarak seçildi. – augustss

3

Ayrıca listeleri herhangi bir sayı birleştirir concat işlevi vardır:

Prelude> :t concat 
concat :: [[a]] -> [a] 
Prelude> concat [[1], [2,3], [42,911]] 
[1,2,3,42,911] 
İlgili konular