GHC.Prim
में, हम एक जादुई समारोह dataToTag# नामित पाते हैं। इसका उपयोग Eq
, Ord
, और Enum
के व्युत्पन्न कार्यान्वयन को तेज़ करने के लिए किया जाता है। GHC स्रोत में, docs for dataToTag#
समझाने कि तर्क पहले से ही द्वारा मूल्यांकन करना चाहिए:dataToTag तर्क की सख़्ती
dataToTag # primop हमेशा एक से मूल्यांकन तर्क करने के लिए लागू की जानी चाहिए। तरीका यह सुनिश्चित करने के लिए GHC.Base में 'getTag' आवरण के माध्यम से यह आह्वान करने के लिए है:
getTag :: a -> Int# getTag !x = dataToTag# x
यह मेरे लिए कुल समझ में आता है कि हमें पहले dataToTag#
कहा जाता है x
के मूल्यांकन के लिए मजबूर करने की जरूरत है। मुझे क्या नहीं मिलता है कि बैंग पैटर्न पर्याप्त क्यों है। getTag
की परिभाषा के लिए बस वाक्यात्मक चीनी है:
getTag :: a -> Int#
getTag x = x `seq` dataToTag# x
लेकिन docs for seq पर गौर करें:
एक नोट मूल्यांकन आदेश पर: अभिव्यक्ति
seq a b
गारंटी नहीं है कि एक ख से पहले मूल्यांकन किया जाएगा। सीईसी द्वारा दी गई एकमात्र गारंटी यह है कि सीईसी एक मूल्य लौटने से पहले ए और बी दोनों का मूल्यांकन किया जाएगा। विशेष रूप से, इसका मतलब है कि बी से पहले मूल्यांकन किया जा सकता है। यदि आपको मूल्यांकन के एक विशिष्ट आदेश की गारंटी देने की आवश्यकता है, तो आपको "समानांतर" पैकेज से फ़ंक्शन पीएसईसी का उपयोग करना होगा।
parallel
पैकेज से Control.Parallel
मॉड्यूल में, डॉक्स elaborate further:
... seq, दोनों अपने तर्कों में सख्त है तो संकलक सकता है, उदाहरण के लिए,
a `seq` b
b `seq` a `seq` b
में पुन: व्यवस्थित .. ।
कैसे यह है कि getTag
काम व्यवहार करने के लिए गारंटी, यह देखते हुए कि seq
मूल्यांकन आदेश को नियंत्रित करने के लिए अपर्याप्त है है?
क्या आप निश्चित हैं कि BangPatterns बस 'seq' के उपयोग में अनुवाद करते हैं? दस्तावेज़ दिखाते हैं कि एक अतिरिक्त 'केस' अभिव्यक्ति भी जोड़ा जाता है। –
@ElliotCameron, वहां कुछ मजेदार जादू है कि मैं वास्तव में समझ में नहीं आता। वे दोनों कोर 'केस' अभिव्यक्तियों को संकलित करते हैं, लेकिन कुछ बंदर व्यवसाय हैं जो उन्हें पुनः लिखने के नियम के बाईं ओर 'seq' से मिलान करने की अनुमति देते हैं। – dfeuer