2015-12-10 2 views
7

ढेर हैकिंग करते हुए मैं this पाया:क्या इकाई पर एक बैंग पैटर्न वास्तव में आवश्यक है?

!() <- atomicModifyIORef (eoExeCache eo) $ \m' -> 
    (Map.insert name epath m',()) 

HLint कहते हैं: "उस चीज़ को दूर"। लेकिन मुझे नहीं लगता कि यह एक टाइपो है। क्या !() लिखने का कोई कारण है?

+3

क्योंकि '()' पहले से ही सामान्य रूप में है (और इसलिए, डब्ल्यूएचएनएफ में), मुझे नहीं लगता कि यहां बैंग पैटर्न का उपयोग करने में कोई बात है। – Jubobs

+1

एक कन्स्ट्रक्टर पैटर्न से पहले एक धमाका व्यर्थ है - हम वैसे भी मूल्य को मजबूर कर रहे हैं। – chi

+2

रेपो की कुछ जांच से पता चलता है कि माइकल स्नोयमैन ने [इस प्रतिबद्धता] में इस बैंग पैटर्न को पेश किया था (https://github.com/commercialhaskell/stack/commit/5039c19655f496926fa882c93efe2867afb97468)। शायद आपको रेपो के इश्यू ट्रैकर में अपना प्रश्न पोस्ट करना चाहिए और उससे पूछना चाहिए कि वह लिखने के समय क्या सोच रहा था। माइकल अपनी चीजें जानता है, इसलिए मैं कहूंगा कि उसने बस इस अनावश्यक धमाके को एक निरीक्षण से छोड़ा था। – Jubobs

उत्तर

6

यदि संदेह में (और जल्दबाजी में नहीं) specification से परामर्श लें।

अभिव्यक्ति

do !() <- foo 
    bar 

desugars

को
let ok !() = bar 
    ok _ = fail .. 
in foo >>= ok 

rules for function definition इस करके

let ok = \x -> case x of !() -> bar 
         _ -> fail ... 
in foo >>= ok 

के बराबर है अब rules for bang patterns, उपयोगकर्ता गाइड GHC में हैं के रूप में यह गैर है मानक मानक हैकेल। वहाँ हम यह है कि हम अपने तर्क जा रहा है ⊥ या नहीं करने के मामले में

let ok = \x -> x `seq` (case x of() -> bar 
            _ -> fail ...) 
in foo >>= ok 

अब seq is defined में इस पुनर्लेखन कर सकते हैं। तो या तो x ⊥ है, लेकिन फिर seq पर दूसरा तर्क, case x of ... भी semantics of pattern matching के अनुसार ⊥ है। या x ⊥ नहीं है, और seq इसके दूसरे तर्क के बराबर है। या तो मामले में, इसके बाद के संस्करण कोड,

let ok = \x -> case x of() -> bar 
         _ -> fail ... 
in foo >>= ok 

जो के समान है वापस इन चरणों का पता लगाने,

do() <- foo 
    bar 
निष्कर्ष में

तो के बराबर है: वहाँ है कि में एक do अभिव्यक्ति करने के लिए कोई कारण नहीं है।

वहाँ तथापि है,

let() = foo 
in bar 

(जहां foo मूल्यांकन किया जा कभी नहीं होगा) और

let !() = foo 
in bar 

क्योंकि जाने-भाव semantics for bang patterns में विशेष प्रावधान है के बीच एक अंतर।

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