2011-05-20 8 views
10

क्या let, where का उपयोग करने का कोई तरीका है या अन्यथा एक सूची समझ में उप-अभिव्यक्ति परिभाषित करें ताकि इसका उपयोग शब्द और बाधा दोनों में किया जा सके?हैकेल - चलो/जहां सूची समझ के बराबर है?

मेरे प्रयोग से, निम्न कार्य:

[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 

लेकिन इन दायरे से बीसी नहीं है:

[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' 

तो एक ही स्थान पर या अन्य में let काम करता है, लेकिन दोनों एक साथ!

एक ही रास्ता मैं यह काम है (यानि, दोहराया भाव और संभवतः मूल्यांकन बचने के लिए) बनाने के लिए मिल गया है एक मूर्खतापूर्ण सिंगलटन-सूची में जोड़ने के लिए है मैं करने के लिए एक constraitnt रूप x<-[e38cat i [1..k] साथ निम्न समस्या (Euler project 38) में किया था के रूप में सूची समझ:

> 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" 

या, ऊपर तुच्छ उदाहरण contunuing,

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

यह एक छोटे से मूर्खतापूर्ण लगता है, और थोड़ा स्पष्टता में कमी है, यद्यपि यह भी अक्षम प्रतीत नहीं होता। फिर भी, यह अच्छा होगा अगर let या where पूरी समझ में काम करता है। क्या यह किया जा सकता है?

+1

आपका दूसरा उदाहरण, '[x | मैं <- [1..10], x = i * i x> 20] में, संकलित नहीं करता; क्या आपका मतलब था '[i * i | मैं <- [1..10], x = i * i x> 20] में? –

+0

हाँ, धन्यवाद। अगर पहले काम किया तो मैंने अपने प्रश्न –

उत्तर

19

आप इसे इस प्रकार लिख:

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

सूचना कोई in। आप दोनों शब्दों में x और let के बाद किसी भी बाधा का उल्लेख कर सकते हैं।

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

यहाँ x दायरे में let से do -block के अंत करने के लिए है: let का यह रूप do -notation में एक से मेल खाती है।

+0

धन्यवाद दिया, मुझे पता था कि कुछ होना था। अगर मैं भाषा = पी –

+1

@jon_darkstar, ओह, बेवकूफ मत बनो तो मैं वास्तव में निराश होता। भाषा में कई अंतर छेद हैं। उदाहरण के लिए, वह 'लागूकर्ता' भरने वाला है। – luqui

5

आपके पास लगभग था; आप बस [x | i <- [0..10], let x = i*i, x > 20] लिख सकते हैं (in के बजाय , पर ध्यान दें)। यह do -notation के समान है (वास्तव में, आप do -notation का उपयोग कर सकते हैं, और हाल ही में जीएचसी एक्सटेंशन आपको मनमाना monads के लिए सूची समझ का उपयोग करने में सक्षम बनाता है)। आप उत्सुक हैं, तो आप वाक्य रचना in the Haskell 98 report पा सकते हैं:

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

आप देख सकते हैं, वैध क्वालिफायर में से एक let decls जो आप वास्तव में क्या करना चाहता था है।

संबंधित मुद्दे