आप अकेले नहीं हैं। seq
शायद कुछ अलग कारणों से, सही तरीके से उपयोग करने के लिए सबसे कठिन हास्केल कार्यों में से एक है। अपने पहले उदाहरण में:
foo s t = seq q (bar q t) where
q = s*t
q
से पहले bar q t
मूल्यांकन किया जाता है मूल्यांकन किया जाता है। यदि bar q t
का मूल्यांकन कभी नहीं किया जाता है, तो q
या तो नहीं होगा। तो अगर आप
main = do
let val = foo 10 20
return()
val
के रूप में इस्तेमाल कभी नहीं किया है, यह मूल्यांकन नहीं किया जाएगा। तो q
का मूल्यांकन नहीं किया जाएगा। आप के बजाय
main = print (foo 10 20)
है, तो foo 10 20
का परिणाम है, (print
द्वारा) मूल्यांकन किया जाता है foo
q
के भीतर ऐसा bar
का परिणाम से पहले मूल्यांकन किया जाता है।
myseq x = seq x x
शब्दार्थ, इसका मतलब है पहले दूसरी x
मूल्यांकन किया जाता है पहले x
मूल्यांकन किया जाएगा:
और इसी कारण यह काम नहीं करता है। लेकिन अगर दूसरा x
कभी मूल्यांकन नहीं किया जाता है, तो पहले व्यक्ति को या तो होने की आवश्यकता नहीं है। तो seq x x
बिल्कुल x
के बराबर है।
आपका दूसरा उदाहरण एक ही चीज़ हो सकता है या नहीं भी हो सकता है। यहां, अभिव्यक्ति s*t
का मूल्यांकन bar
के आउटपुट से पहले किया जाएगा, लेकिन यह के पहले पैरामीटर के समान s*t
नहीं हो सकता है। यदि संकलक सामान्य उप-अभिव्यक्ति उन्मूलन करता है, तो यह दो समान अभिव्यक्तियों को आम कर सकता है। हालांकि, सीएसई कहां से जीएचसी काफी रूढ़िवादी हो सकता है, इसलिए आप इस पर भरोसा नहीं कर सकते हैं। यदि मैं bar q t = q*t
को परिभाषित करता हूं तो यह सीएसई करता है और बार में उस मान का उपयोग करने से पहले s*t
का मूल्यांकन करता है। यह अधिक जटिल अभिव्यक्तियों के लिए ऐसा नहीं कर सकता है।
आप यह भी जानना चाहेंगे कि सख्त मूल्यांकन क्या है।seq
कमजोर सिर सामान्य रूप (डब्ल्यूएचएनएफ) के पहले तर्क का मूल्यांकन करता है, जो डेटा प्रकारों के लिए बाहरीतम कन्स्ट्रक्टर को अनपॅक करना है। इस पर विचार करें:
baz xs y = seq xs (map (*y) xs)
xs
map
की वजह से सूची होनी चाहिए। जब seq
यह मूल्यांकन करता है, यह अनिवार्य रूप से
case xs of
[] -> map (*y) xs
(_:_) -> map (*y) xs
में कोड बदल सकते हैं इसका मतलब यह है यह तय करेंगे यदि सूची खाली है या नहीं, तो दूसरा तर्क लौटने। ध्यान दें कि सूची मूल्यों में से कोई भी मूल्यांकन नहीं किया गया है। तो अगर आप ऐसा कर सकते हैं:
Prelude> seq [undefined] 4
4
लेकिन इस
Prelude> seq undefined 5
*** Exception: Prelude.undefined
जो भी डेटा प्रकार आप seq
पहला तर्क के लिए उपयोग करते हैं, WHNF करने का मूल्यांकन अब तक निर्माता और आगे नहीं यह पता लगाने के लिए पर्याप्त नहीं होगा नहीं। जब तक डेटा प्रकार में ऐसे घटक नहीं होते हैं जिन्हें बैंग पैटर्न के साथ सख्त के रूप में चिह्नित किया जाता है। फिर सभी सख्त क्षेत्रों का मूल्यांकन डब्ल्यूएचएनएफ को भी किया जाएगा।
संपादित करें: (टिप्पणी में सुझाव के लिए डैनियल वैगनर के लिए धन्यवाद)
कार्यों के लिए, जब तक समारोह है, जिसका अर्थ है कि यह आवेदन के लिए तैयार है "एक लैम्ब्डा दिखा है" seq
अभिव्यक्ति का मूल्यांकन करेंगे।
-- ok, lambda is outermost
Prelude> seq (\x -> undefined) 'a'
'a'
-- not ok. Because of the inner seq, `undefined` must be evaluated before
-- the lambda is showing
Prelude> seq (seq undefined (\x -> x)) 'b'
*** Exception: Prelude.undefined
आप एक लैम्ब्डा एक (बिल्ट-इन) डेटा निर्माता के रूप में बाध्यकारी के बारे में सोच रहे हैं, तो seq
कार्यों पर डेटा पर उपयोग के साथ पूरी तरह अनुरूप है: यहाँ कुछ उदाहरण का प्रदर्शन हो सकता है कि इसका क्या मतलब है।
इसके अलावा, "लैम्ब्डा बाध्यकारी" सभी प्रकार की फ़ंक्शन परिभाषाओं को कम करता है, चाहे लैम्ब्डा नोटेशन द्वारा परिभाषित किया गया हो या सामान्य कार्य के रूप में।
Controversy हास्केलविकि के सीक पृष्ठ के अनुभाग में कार्यों के संबंध में seq
के कुछ परिणामों के बारे में कुछ नहीं है।
यह सहायक हो सकता है: http://stackoverflow.com/questions/6872898/haskell-what-is-weak-head-normal-form "इसके अर्थशास्त्र यह है कि seq xy का अर्थ है कि जब भी y को कमजोर सिर के लिए मूल्यांकन किया जाता है फॉर्म, एक्स का भी कमजोर सिर सामान्य रूप में मूल्यांकन किया जाता है। " – shang