2012-05-01 76 views
14

मैं Gentle Introduction के माध्यम से पढ़ रहा हूं और सोच रहा हूं कि क्यों दो जनरेटर के साथ एक सूची समझ में, सही जनरेटर को "सबसे तेज़" (यानी सबसे निचले लूप के लिए संकलित करता है) अनुमानित किया जाता है। निम्नलिखित GHCi उत्पादन का निरीक्षण करें:क्यों सघनतम लूप के रूप में सबसे दायीं ओर का जनरेटर का इलाज कई जनरेटर के साथ हास्केल सूची comprehensions करते हैं?

*Main> concat [[(x,y) | x <- [0..2]] | y <- [0..2]] 
[(0,0),(1,0),(2,0),(0,1),(1,1),(2,1),(0,2),(1,2),(2,2)] 
*Main> [(x,y) | x <- [0..2], y <- [0..2]] 
[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)] 

तो वाम-पंथी जनरेटर सबसे तेजी से दोहराया गया, ऊपर दो भाव एक ही मूल्य है, जो मुझे लगता है कि किसी भी तरह इस सम्मेलन और अधिक प्राकृतिक चुनने बनाता होगा।

तो किसी को पता है क्यों विपरीत सम्मेलन में चुना गया था? मैं नोटिस अजगर हास्केल (भी हो सकता है हास्केल से उधार ली गई?) के रूप में ही सम्मेलन है, और अजगर दुनिया में the word है कि आदेश में चुना गया था "क्योंकि है कि जिस क्रम में आप पाश के लिए एक लिखते हैं कि" लगता है, लेकिन मुझे लगता है छोरों के लिए के मामले में है कि सोच इकट्ठा

विचार जो सबसे हास्केल प्रोग्रामर करना बिल्कुल नहीं है ...?


नीचे लुइस Wasserman के जवाब पर मेरी टिप्पणी से:

मैं यहाँ लगता है कि समझ के एक अनिवार्य शैली व्याख्या करने के लिए इसी क्रम में यह सूची घोंसले के अनुरूप होने की तुलना में अधिक प्राकृतिक माना जाता था। तो संक्षेप में इस के लिए हास्केल स्पष्टीकरण अजगर स्पष्टीकरण मैं प्रश्न में जुड़े हुए के समान ही है, सब के बाद, ऐसा लगता है।

+0

यह * अधिक प्राकृतिक * कैसे होगा? क्या आप 11, 12, 13, 14 के बजाय 11, 21, 31, 41 भी चाहते हैं? – Ingo

+0

मुझे अनुमान है कि '(वाई, एक्स)' प्रोटोटाइपिकल अभिव्यक्ति के रूप में - या वाई जनरेटर को एक्स जनरेटर के बाईं ओर डालने का अनुमान है - अगर बाएं जेनरेटर सबसे कड़े लूप थे तो अधिक समझ में आ जाएगा। फिर यह मेरे जीएचसीआई आउटपुट में दूसरी पंक्ति होगी जो आपको पहले की तुलना में अजीब लगती है (11, 21, 31, 41), लेकिन वे अभी भी एक दूसरे से अलग होंगे, जो मेरा मुद्दा है। – kini

+0

क्षमा करें, मुझे लगता है कि आपको जवाब देने पर मुझे आपको संबोधित करना चाहिए, @Ingo। (स्टैक ओवरफ़्लो के लिए नया प्रकार।) – kini

उत्तर

21

तो है कि एक समझदार तरीके से काम गुंजाइश। xy पर समझ के लिए दायरे में है - -

[(x, y) | x <- [1..10], y <- [1..x]] 

समझ में आता है लेकिन

[(x, y) | y <- [1..x], x <- [1..10]] 

कुछ हद तक कम समझ में आता है।

साथ ही, इस तरह से यह do इकाई वाक्य रचना के साथ संगत है:

do x <- [1..10] 
    y <- [1..x] 
    return (x, y) 
+3

यह दिखाने के लिए एक अच्छा विचार हो सकता है कि एक ही कोड 'डी' मोनैड सिंटैक्स का उपयोग करके अनियमित के लिए कैसे दिखाई देगा। – dflemstr

+0

हम्म। शुरुआत के रूप में, मैं वास्तव में नहीं देखता कि जेनरेटर के आदेश से स्कोपिंग कम मनमानी कैसे है। फिर से मेरे घोंसले उदाहरण का उपयोग, '[[(एक्स, वाई) | एक्स <- [1..10]] | वाई <- [1..एक्स]] 'समझ में नहीं आता है, जबकि' [[(x, y) | वाई <- [1..एक्स]] | एक्स <- [1..10]] 'समझ में आता है। – kini

+2

नेस्टिंग (और होने का मतलब है) जंजीर समझ वाक्यविन्यास से बिल्कुल अलग है। किसी भी घटना में, 'डू' नोटेशन का एक अनौपचारिक आदेश होता है जिसमें सूची की समझें सहमत होती हैं। –

0

असल में अजगर सूची comprehensions के लिए हास्केल के रूप में ही गुंजाइश संरचना का उपयोग करता।

अपने हास्केल की तुलना करें:

*Main> concat [[(x,y) | x <- [0..2]] | y <- [0..2]] 
[(0,0),(1,0),(2,0),(0,1),(1,1),(2,1),(0,2),(1,2),(2,2)] 
*Main> [(x,y) | x <- [0..2], y <- [0..2]] 
[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)] 

इस अजगर के साथ:

>>> from itertools import chain 
>>> list(chain(*[[(x,y) for x in range(3)] for y in range(3)])) 
[(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)] 
>>> [(x,y) for x in range(3) for y in range(3)] 
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 
>>> 
+0

ओह, आप पहले ही जानते थे। किसी भी तरह से, मैं इसे तुलना के लिए यहां छोड़ दूंगा। –

+0

एर, हाँ, यही मेरा मतलब था :) मैं स्पष्टता के लिए अपना प्रश्न संपादित करूंगा। – kini

6

यह अधिक अर्थपूर्ण हो सकता है अगर आप monadic बांध में do अंकन में पहली सूची समझ का विस्तार और उसके बाद।

[ (x,y) | x <- [1,2,3], y <- [x+1,x+2] ] 

यह फैलता

do x <- [1,2,3] 
    y <- [x+1,x+2] 
    return (x,y) 

जो

[1,2,3] >>= \x -> 
[x+1,x+2] >>= \y -> 
return (x,y) 

जो यह स्पष्ट करता है के लिए विस्तारित करने के लिए: मान लीजिए हम एक समझ लिखना चाहते हैं जहां हम ऐसे नाम हैं जो पहले से ही बाध्य कर रहे हैं से देख चलो कि x दायरे में ठीक है जब इसे होने की आवश्यकता है।

तो do अंकन में विस्तार हुआ सही-से-बाएँ के बजाय बाएँ-से-सही, तो हमारे मूल अभिव्यक्ति

[x+1,x+2] >>= \y -> 
[1,2,3] >>= \x -> 
return (x,y) 

में विस्तार होगा जो स्पष्ट रूप से अतर्कसंगत है - यह x का मूल्य को संदर्भित करता है एक दायरे में जहां x अभी तक बाध्य नहीं है। इसलिए हम अपने मूल समझ लिखने के रूप में

[ (x,y) | y <- [x+1,x+2], x <- [1,2,3] ] 

परिणाम हम चाहते थे, जो अप्राकृतिक लगता भी प्राप्त करना होगा - समय में वाक्यांश y <- [x+1,x+2] पर अपने आंख स्कैन आप वास्तव में नहीं पता है कि x है। पता लगाने के लिए आपको पीछे की समझ को पढ़ना होगा।

तो यह जरूरत नहीं चाहते मामला है कि सबसे-दाएं बंधन "आंतरिक पाश" में unrolled है, लेकिन यह समझ में आता है जब आप समझते हैं कि मनुष्य जिसके परिणामस्वरूप कोड को पढ़ने के लिए जा रहे हैं ।

+0

हां, आप लुई वासरमैन के जवाब के समान अंक बनाते हैं, मुझे लगता है।लेकिन अगर तर्क वास्तव में स्कॉइंग ऑर्डर के साथ गठबंधन किया गया है (अंग्रेजी बोलने वाले) इंसानों को बाएं से दाएं पढ़ने के लिए फिट करने के लिए बाएं से दाएं, तो अभिव्यक्ति ('(x, y)') के बाईं ओर क्यों है इसके चर के मात्रा? वास्तव में, क्यों न सिर्फ निर्देशों के monadic आदेश का पालन करें, ताकि '[1,2,3] >> = \ x -> [x + 1, x + 2] >> = \ y -> वापसी (एक्स, वाई) 'कहा गया था,' [x <- [1,2,3], वाई <- [x + 1, x + 2] | (एक्स, वाई)] '? – kini

+0

इसे एक और तरीका रखने के लिए, सही, जब आप 'y <- [x + 1, x + 2]' स्कैन करते हैं, तो आप वास्तव में नहीं जानते कि 'x' क्या है, लेकिन जब आप' (x, y) स्कैन करते हैं, , आप नहीं जानते कि 'x' या 'y' में से कोई भी या तो है। – kini

+2

यह एक वैध बिंदु है। मुझे इस तरह लिखने का कारण संदेह है कि यह गणितीय [सेट-बिल्डर नोटेशन] समानांतर है (http://en.wikipedia.org/wiki/Set-builder_notation#Parallels_in_programming_languages) (याद रखें कि हास्केल के गणित से कई प्रभाव हैं)। यदि यह आपकी मदद करता है - मैं हमेशा लंबवत बार '|' को "कहां" के रूप में पढ़ता हूं (मैं इसे "ऐसे" के रूप में पढ़ता था, जिस दिन मैंने प्रोग्रामर की तुलना में गणितज्ञ के बारे में अधिक जानकारी दी थी ...) –

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

  • कोई संबंधित समस्या नहीं^_^