2009-12-30 13 views
73

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

+1

//, क्या इस तरह की राय की बात नहीं है, हालांकि? –

उत्तर

88

वास्तव में कठिन सवाल है। मुझे आशा है कि आपके उत्तर कुछ अच्छा हो जाएंगे। इस बीच, यहां गलतियों या अन्य परेशान चीजों की एक सूची है जिसे मैंने शुरुआती कोड में पाया है। कैल टेक स्टाइल पेज के साथ कुछ ओवरलैप है जो कॉर्नेल किस्लेविच ने इंगित किया है। मेरी सलाह के कुछ रूप में हर बिट अस्पष्ट और HaskellWiki "जवाहरात" के रूप में बेकार है, लेकिन मुझे उम्मीद है कि कम से कम यह बेहतर सलाह :-) अपने कोड

  • स्वरूप तो यह 80 कॉलम में फिट बैठता है। (उन्नत उपयोगकर्ताओं 87 या 88 पसंद कर सकते हैं; परे है कि यह धक्का है।)

  • मत भूलना कि let बाइंडिंग और where खंड परिभाषाओं की एक पारस्परिक रूप से पुनरावर्ती घोंसला बनाते हैं, नहीं एक अनुक्रम परिभाषा के

  • where खंडों का लाभ उठाएं, विशेष रूप से उन कार्यों के पैरामीटर को देखने की उनकी क्षमता जो पहले से ही दायरे में हैं (अच्छी अस्पष्ट सलाह)। यदि आप वास्तव में हास्केल को गड़बड़ कर रहे हैं, तो आपके कोड में where-let-बाइंडिंग की तुलना में बाइंडिंग बहुत अधिक होनी चाहिए। बहुत सारे let-बाइंडिंग एक अपरिवर्तित एमएल प्रोग्रामर या लिस्प प्रोग्रामर का संकेत है।

  • अनावश्यक ब्रांड्स से बचें। कुछ स्थानों पर जहां अनावश्यक कोष्ठकों विशेष रूप से आक्रामक हैं

    • एक if अभिव्यक्ति में हालत के आसपास (एक unreconstructed सी प्रोग्रामर के रूप में ब्रांडों आप)

    • एक समारोह आवेदन जो अपने आप में एक इन्फ़िक्स ऑपरेटर का तर्क है चारों ओर (समारोह आवेदन किसी भी इन्फ़िक्स ऑपरेटर से तंग बांधता है। इस तथ्य को ठीक उसी तरह है कि हम डायनासोर था में, हर Haskeller के मस्तिष्क में जला दिया जाना चाहिए एपीएल का सही-से-बाएँ नियम स्कैन में जला दिया।)

  • इंफिक्स ऑपरेटरों के आसपास रिक्त स्थान रखें। एक अल्पसंख्यक शाब्दिक में प्रत्येक अल्पविराम के बाद एक जगह रखें।

  • किसी फ़ंक्शन और उसके तर्क के बीच एक स्थान को प्राथमिकता दें, भले ही तर्क को संश्लेषित किया गया हो।

  • $ ऑपरेटर को समझदारी से ब्रांड्स पर कटौती करने के लिए उपयोग करें। $ और इन्फ़िक्स . के बीच घनिष्ठ संबंधों के प्रति सचेत रहें:

    f $ g $ h x == (f . g . h) x == f . g . h $ x 
    
  • को नजरअंदाज न करें Maybe निर्मित और Either प्रकार के।

  • कभी भी if <expression> then True else False लिखें; सही वाक्यांश बस <expression> है।जब आप पैटर्न मिलान का उपयोग कर सकता है

  • head या tail प्रयोग न करें।

  • इन्फ़िक्स डॉट ऑपरेटर के साथ समारोह रचना को नजरअंदाज न करें।

  • सावधानीपूर्वक लाइन ब्रेक का उपयोग करें। लाइन ब्रेक पठनीयता में वृद्धि कर सकते हैं, लेकिन एक ट्रेडऑफ है: आपका संपादक एक बार में केवल 40-50 लाइनों को प्रदर्शित कर सकता है। यदि आपको एक बार में एक बड़े फ़ंक्शन को पढ़ने और समझने की आवश्यकता है, तो आपको लाइन ब्रेक का उपयोग नहीं करना चाहिए।

  • लगभग हमेशा -- टिप्पणियां पसंद करते हैं जो {- ... -} टिप्पणियों पर लाइन के अंत तक चलती हैं। ब्रेसिड टिप्पणियां बड़े शीर्षलेख — के लिए उपयुक्त हो सकती हैं।

  • प्रत्येक शीर्ष स्तर समारोह एक स्पष्ट प्रकार हस्ताक्षर दे।

  • जब संभव हो, -- लाइनें, = संकेत, और यहां तक ​​कि ब्रांड्स और कॉमा जो निकटवर्ती रेखाओं में होते हैं संरेखित करें।

  • प्रभावित के रूप में मैं GHC केंद्रीय द्वारा हूँ, मैं स्थानीय where -bound या let -bound चर के लिए निर्यात किया पहचानकर्ता के लिए camelCase और short_name अंडरस्कोर से उपयोग करने के लिए एक बहुत ही हल्के प्राथमिकता है।

+3

मुझे वास्तव में यह जवाब पसंद है, लेकिन क्या आप कुछ और कोड नमूने प्रदान कर सकते हैं?मैं अभी भी हास्केल लिंगो से पूरी तरह से परिचित नहीं हूं, इसलिए "फंक्शन एप्लिकेशन किसी भी इंफिक्स ऑपरेटर से कड़ा बांधता है" और कुछ अन्य बिंदु मुझे परेशान करते हैं। – CaptainCasey

+2

@ कैप्टन कैसी: मैंने कुछ उदाहरण जोड़ना शुरू कर दिया, लेकिन फिर जवाब बहुत लंबा और पढ़ने के लिए मुश्किल हो गया। यह सुझावों का एक छोटा सा सेट के रूप में है; यदि यह वास्तविक शैली मार्गदर्शिका में बदलना है, तो इसे किसी और द्वारा किया जाना होगा। लेकिन मुझे अपने विशिष्ट बिंदुओं को बताने दें। बाध्यकारी मजबूती का मतलब है कि '(लंबाई एल) + 1' बदसूरत है। 'लंबाई' का उपयोग स्वचालित रूप से '+' के अनुप्रयोग से अधिक कठिन होता है, इसलिए लिखने की मूर्खतापूर्ण चीज़ 'लंबाई एल + 1' है। पेंटिचेस कार्यात्मक कार्यक्रमों का केंद्र हैं। –

+0

^यहां तक ​​कि लिस्सेल का झुकाव भी? –

6

मैं इस style checker पर एक नज़र डालने का सुझाव दूंगा।

+8

और एचलिंट http://hackage.haskell.org/package/hlint –

6
  • मैं तरह बातें करने से संभव के रूप में जितना बिंदु मुक्त शैली रचनाओं के रूप में कार्य व्यवस्थित करने के लिए कोशिश करना:

    func = boo . boppity . bippity . snd 
        where boo = ... 
          boppity = ... 
          bippity = ... 
    
  • मैं ($) का उपयोग कर पसंद केवल नेस्टेड कोष्ठक या लंबी parenthesized भाव

  • से बचने के लिए ... मैंने सोचा कि मैं मुझ में कुछ और था, ओह अच्छी तरह से

26

अंगूठे से कुछ अच्छा नियम imho:

  • HLint के साथ परामर्श करें सुनिश्चित करें कि आप अनावश्यक ब्रेसिज़ नहीं है और निरर्थक रूप से इंगित भरा नहीं है कि अपने कोड है बनाने के लिए।
  • मौजूदा लाइब्रेरी फ़ंक्शंस को पुनर्निर्मित करने से बचें। Hoogle आपको ढूंढने में मदद कर सकता है।
    • अक्सर मौजूदा पुस्तकालय कार्यों क्या एक बनाने के लिए जा रहा था की तुलना में अधिक सामान्य हैं। उदाहरण के लिए यदि आप Maybe (Maybe a) -> Maybe a चाहते हैं, तो join अन्य चीजों के साथ करता है।
  • तर्क नामकरण और प्रलेखन कभी कभी महत्वपूर्ण है।
    • replicate :: Int -> a -> [a] जैसे फ़ंक्शन के लिए, यह स्पष्ट है कि प्रत्येक तर्क अकेले उनके प्रकार से क्या करता है।
    • एक समारोह है कि isPrefixOf :: (Eq a) => [a] -> [a] -> Bool की तरह, एक ही प्रकार के कई तर्क लेता है, नामकरण के लिए/बहस के प्रलेखन अधिक महत्वपूर्ण है।
  • एक समारोह मौजूद है, तो केवल एक और समारोह की सेवा के लिए है, न कि अन्यथा उपयोगी है, और/या यह इसके लिए एक अच्छा नाम के बारे में सोचना मुश्किल है, तो यह शायद उस में मौजूद होना चाहिए में के बजाय फोन करने वाले का where खंड है मॉड्यूल का दायरा
  • DRY
    • उपयुक्त होने पर टेम्पलेट-हास्केल का उपयोग करें।
    • zip3, zipWith3, zip4, zipWith4, आदि जैसे कार्यों के बंडल बहुत मेह हैं। इसके बजाय ZipList एस के साथ Applicative शैली का उपयोग करें। आपको शायद उन लोगों के कार्यों की वास्तव में आवश्यकता नहीं है।
    • स्वचालित रूप से घटनाएं उत्पन्न करें। derive पैकेज आपको Functor जैसे प्रकार-वर्गों के लिए उदाहरण प्राप्त करने में मदद कर सकता है (Functor का उदाहरण बनाने के लिए केवल एक सही तरीका है)।
  • कोड अधिक व्यापक कई लाभ हैं:
    • यह अधिक उपयोगी और पुन: प्रयोज्य है।
    • यह बग्स से कम प्रवण है क्योंकि अधिक बाधाएं हैं।
      • उदाहरण के लिए आप concat :: [[a]] -> [a] कार्यक्रम, और ध्यान दें कि यह कैसे join :: Monad m => m (m a) -> m a के रूप में अधिक सामान्य हो सकता है करना चाहते हैं। join प्रोग्रामिंग करते समय त्रुटि के लिए कम जगह है क्योंकि प्रोग्रामिंग concat जब आप गलती से सूचियों को उलट सकते हैं और join में बहुत कम चीजें हैं जो आप कर सकते हैं।
  • अपने कोड में कई स्थानों पर इकाई ट्रांसफार्मर का एक ही ढेर का उपयोग करते समय के लिए एक प्रकार का पर्याय हैं। यह थोक में संशोधित करने के लिए छोटे, अधिक संक्षेप और आसान बना देगा।
  • "आलसी आईओ" से सावधान रहें। उदाहरण के लिए readFile फ़ाइल पढ़ने के पल में फ़ाइल की सामग्री को वास्तव में नहीं पढ़ता है।
  • इतनी इंडेंटिंग से बचें कि मुझे कोड नहीं मिल रहा है।
  • यदि आपका प्रकार तर्कसंगत रूप से टाइप-क्लास का उदाहरण है, तो इसे एक उदाहरण बनाएं।
    • उदाहरण परिचित लोगों के साथ अन्य इंटरफ़ेस फ़ंक्शंस को प्रतिस्थापित कर सकता है।
    • नोट: यदि एक से अधिक लॉजिकल इंस्टेंस हैं, तो उदाहरणों के लिए न्यूटाइप-रैपर बनाएं।
    • विभिन्न उदाहरणों को सुसंगत बनाएं। अगर ApplicativeZipList की तरह व्यवहार किया गया तो यह बहुत भ्रमित/बुरा होता।
4

मैं Haskell कोड शैली के लगभग हर पहलू को कवर अच्छा markdown फ़ाइल मिली। इसे धोखा शीट के रूप में इस्तेमाल किया जा सकता है। आप इसे यहां पा सकते हैं: link

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