2011-06-27 12 views
25

मैंने निम्नलिखित कोड लिखा, जो अंक का एक गुच्छा लेता है और चमक पुस्तकालय का उपयोग करके उन्हें स्क्रीन पर खींचता है।बिंदु मुफ्त कोड अधिक कुशल है, या सिर्फ terser?

let s = blocks pes 
    pts = map (map mkPt) s {- stitches to points-} 
    lines = map Line pts {-points to lines -} 
    pict = Pictures lines {- lines to a picture -} 
    in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

यह ठीक काम करता है, लेकिन यह एक दोहराया पैटर्न है कि मेरे पास होता है: फ़ंक्शन कॉल की एक श्रृंखला है, अगले के अंतिम बहस में खिला हर एक का परिणाम है। तो मैं, मध्यवर्ती चर को हटाने के आदेश को पलटने और ("।") समारोह संरचना के साथ काम करता है चेनिंग तो तरह से पुनर्संशोधित:

let pict = Pictures . (map Line) . (map $ map $ mkPt) . blocks $ pes 
       in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

सौभाग्य से, यह भी ठीक काम करता है। लेकिन मुझे आश्चर्य है कि क्या मैं पठनीयता को दबा रहा हूं, या अगर मुझे & लेखन बिंदु मुक्त शैली कोड पढ़ने के लिए उपयोग नहीं किया जाता है। इसके अलावा, मैं इस कोड के बारे में कैसे तर्क करूं? क्या दूसरा संस्करण अधिक कुशल है, या बस terser? क्या यह कुछ भी है जो मैं इसे स्पष्ट बनाने के लिए स्टाइलिस्टिक रूप से कर सकता हूं?

उत्तर

31

कुछ त्वरित सुझाव:

let pict = Pictures . (map Line) . (map $ map $ mkPt) . blocks $ pes 
in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

आप कुछ ज़रूरत से ज़्यादा सामान है कि एकमुश्त हटाया जा सकता है मिल गया है:

let pict = Pictures . map Line . (map $ map mkPt) . blocks $ pes 
in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

आप map (map mkPt) अवधि के साथ वैसे भी कोष्ठकों से परहेज नहीं कर रहे हैं, तो मिलता है $ से छुटकारा:

let pict = Pictures . map Line . map (map mkPt) . blocks $ pes 
in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

आप कर सकते हैं स्पष्टता के लिए एकाधिक पंक्तियों में रचना श्रृंखला ते:

let pict = Pictures 
     . map Line 
     . map (map mkPt) 
     . blocks $ pes 
in do displayInWindow "My Window" (200, 200) (10, 10) white pict 

do ब्लॉक ज़रूरत से ज़्यादा है, क्योंकि यह केवल एक ही बयान है, और आप परिभाषा के बाहर अंतिम आवेदन स्थानांतरित कर सकते हैं:

let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white 
       . Pictures 
       . map Line 
       . map (map mkPt) 
       . blocks 
in displayPict pes 

आप मर्ज कर सकते हैं दो map रों:

let displayPict = displayInWindow "My Window" (200, 200) (10, 10) white 
       . Pictures 
       . map (Line . map mkPt) 
       . blocks 
in displayPict pes 

कभी कभी यह भी अधिक पठनीय है लंबी श्रृंखला उलट रचना ओपेरा का उपयोग करने के लिए Control.Arrow से टो:

let displayPict = blocks 
        >>> map (Line . map mkPt) 
        >>> Pictures 
        >>> displayInWindow "My Window" (200, 200) (10, 10) white 
in displayPict pes 

लेकिन उस के सभी वैकल्पिक है; स्वाद के लिए अपने कोड का मौसम।

दक्षता के विषय पर, मुझे यह सोचने का कोई कारण नहीं है कि जीएचसी का अनुकूलक कोड के माध्यम से एक बार अलग होगा।

+4

दरअसल, उत्पन्न कोड बिंदु मुक्त संस्करण के लिए समान होना चाहिए। किसी भी अनुकूलन के बिना बिंदु मुक्त कोड थोड़ा कम कुशल होगा, क्योंकि इसमें अधिक फ़ंक्शन कॉल (संरचना का) है। – augustss

+0

वाह, यह सुंदर है मुझे उलटा रचना ऑपरेटर के बारे में पता नहीं था। धन्यवाद! – nont

+1

@augustss: पुष्टिकरण के लिए धन्यवाद - मैं निश्चित नहीं था, लेकिन पुनर्गठन सभी बहुत ही तुच्छ हैं और उप-अभिव्यक्तियों के संभावित पुनर्मूल्यांकन के रूप में कोई अंतर नहीं दिखता है। मैं "अनुकूलन" परिदृश्य के बारे में चिंता न करें जब तक कि अंतर गंभीर न हो, उदा। 'foldl' को 'foldl' में बदलने के लिए सख्तता विश्लेषक पर भरोसा करना मुझे असहज बनाता है। –

4

प्वाइंट फ्री स्टाइल बहुत स्पष्ट रूप से यह दिखाने के लिए अच्छा हो सकता है कि एक फ़ंक्शन केवल इनपुट पर परिवर्तनों की एक श्रृंखला है। ऐसा लगता है कि कुछ पढ़ने के वास्तव में आसान है:

foo = map show . doThis . doThat . etc 

क्योंकि यह ठेठ बिंदु मुक्त कोड की तरह लग रहा है, तो किसी को इससे परिचित वास्तव में क्या महत्वपूर्ण है, कोई शोर के साथ देखने के लिए सक्षम हो जाएगा। को यह तुलना करें:

foo x = d 
    where 
     a = etc x 
     c = doThis b 
     b = doThat a 
     d = map show c 

जाहिर है, इस एक छोटे से काल्पनिक है, लेकिन विचार है कि अतिरिक्त परिभाषाओं पढ़ने के लिए और बारीकी से समझने के लिए क्या foo वास्तव में क्या कर रहा है क्रम में करने के लिए ध्यान दिया की जरूरत है।a एक से अधिक सहायक फ़ंक्शन के लिए तर्क के रूप में उपयोग किया जाता है? b के बारे में क्या? क्या डेटा ने इन सहायक कार्यों के माध्यम से अप्रत्याशित रूप से प्रवाह किया था? इस मामले में प्वाइंट फ्री स्टाइल कह रही है, "चीजों को सिर्फ एक पाइपलाइन में बदल दिया जा रहा है,"

अन्य मामलों में, बिंदु-मुक्त शैली वास्तव में चीजों को खराब कर सकती है। आम तौर पर जब आप चलो और wheres तोड़ देंगे। तो, दृढ़ता वास्तव में एकमात्र लक्ष्य नहीं है, मानसिक भार को कम करना भी महत्वपूर्ण है। (जैसा कि अन्य ने टिप्पणी की है, इंगित करें कि मुक्त शैली को अनुकूलित कोड में प्रदर्शन अंतर नहीं होना चाहिए)।

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