2011-05-20 20 views
10

let, where'un bir yolu var mı yoksa alt terimleri bir liste kavrayışında tanımlayın, böylece hem terim hem de kısıtlamada kullanılabilir mi? Benim Deneme yaparken itibarenhaskell - liste kavramasında eşdeğer nerede?

aşağıdaki çalışma:

[let x = i*i in x | i<-[1..10], i*i > 20] --good 
[i*i | i<-[1..10], let x=i*i in x > 20]  --good 

Fakat bu kapsam bc yok:

[let x = i*i in x | i<-[1..10], x > 20] -- 'x' not in scope error 
let x = i*i in [x | i<-[1..10], x > 20] -- 'i' not in scope error 
[x | i<-[1..10], x > 20] where x = i*i --parse error on 'where' 

Yani bir yerde veya diğerinde let eserler, ancak ikisini bir arada!

Çalışmasını sağlamanın tek yolu (yani, yinelenen ifadelerden ve olası değerlendirmelerden kaçınmak), aşağıdaki soruna (Euler project 38) x<-[e38cat i [1..k] kodlu bir tek liste halinde eklemek liste anlama: çok verimsiz görünmüyor tho yukarıda önemsiz örneği contunuing

> let e38cat x l = foldl1 (++) $ map show [x*i | i<-l] 
maximum [x| i<-[1..9999], k<-[2..div 10 $ length $ show i], x<-[e38cat i [1..k]], sort x == "123456789"] 
"932718654" 

Veya,

[x | i<-[0..10], x<-[i*i], x > 20] --works 

Bu, biraz aptalca görünüyor ve biraz netlik yoksundur. Yine de, let veya where tüm anlamada işe yarayacaktır. Bu yapılabilir mi?

+1

İkinci örneğiniz, '[x | i <- [1..10], x = i * i x> 20] 'ye izin vermeyin; demek istediniz [i * i | i <- [1..10], x = i * i x> 20] 'ye izin verin? –

+0

evet, teşekkürler. ilk çalıştı eğer ben kendi soru –

cevap

19

Böyle yazmak:

[x | i <- [0..10], let x = i*i, x > 20] 

Bildirimi hiçbir in yoktur. Her iki terimde de x ve let'u izleyen tüm kısıtlamalara başvurabilirsiniz. Burada x

do i <- [0..10] 
    let x = i*i 
    guard (x > 20) 
    return x 

do -bloku sonuna let den kapsamında olup: let bu şekli do -notation içinde birine karşılık gelir.

+0

teşekkürler cevap verdim, bir şey olması gerektiğini biliyordum. Eğer bu sadece bir dilenme deliği = P –

+1

@ jon_darkstar ise ahlaksız olmayın diye hayal kırıklığına uğramış olurdum. Dilde çok sayıda boşluk deliği vardır. Örneğin, “Uygulamanın” doldurması gereken bir şey. – luqui

5

Neredeyse hiç vardı; [x | i <- [0..10], let x = i*i, x > 20] yazabilirsiniz (in yerine ,). do-notasyonuna çok benzer (aslında, do -notation kullanıp son zamanlardaki GHC eklentisi, rasgele monadlar için liste kavramalarını kullanmanıza olanak tanır). Merak ediyorsanız, sözdizimi in the Haskell 98 report bulabilirsiniz:

aexp -> [ exp | qual_1 , ... , qual_n ] (list comprehension, n >= 1) 
qual -> pat <- exp      (generator) 
    | let decls      (local declaration) 
    | exp        (guard) 

Gördüğünüz gibi, geçerli elemeleri biri istediğini tam olarak ne olduğu, let decls olduğunu.