Haskell Language
सख़्ती
खोज…
बैंग पैटर्न
बैंग ( !
) के साथ एनोटेट किए गए पैटर्नों का मूल्यांकन आलसी के बजाय कड़ाई से किया जाता है।
foo (!x, y) !z = [x, y, z]
इस उदाहरण में, सूची वापस करने से पहले x
और z
दोनों का मूल्यांकन कमजोर सिर सामान्य रूप में किया जाएगा। यह इसके बराबर है:
foo (x, y) z = x `seq` z `seq` [x, y, z]
बैंग पैटर्न Haskell 2010 BangPatterns
भाषा एक्सटेंशन का उपयोग कर सक्षम होते हैं।
सामान्य रूप
यह उदाहरण एक संक्षिप्त अवलोकन प्रदान करता है - सामान्य रूपों और उदाहरणों की अधिक गहराई से व्याख्या के लिए, इस प्रश्न को देखें।
सामान्य रूप में कमी
किसी अभिव्यक्ति का घटा हुआ सामान्य रूप (या केवल सामान्य रूप, जब संदर्भ स्पष्ट होता है) दिए गए अभिव्यक्ति में सभी reducible subexpressions का मूल्यांकन करने का परिणाम है। हास्केल के गैर-सख्त शब्दार्थ (जिसे आमतौर पर आलस्य कहा जाता है ) के कारण, एक उपप्रकार प्रति ग्रहणशील नहीं है यदि यह एक बांधने की मशीन के नीचे है (यानी एक लैम्ब्डा एब्स्ट्रक्शन - \x -> ..
)। एक अभिव्यक्ति के सामान्य रूप में संपत्ति है कि अगर यह मौजूद है, तो यह अद्वितीय है।
दूसरे शब्दों में, इससे कोई फर्क नहीं पड़ता है (संप्रदाय शब्दार्थों के संदर्भ में) जिस क्रम में आप सबटेक्शंस को कम करते हैं। हालांकि, प्रदर्शन करने वाले हस्केल कार्यक्रमों को लिखने की कुंजी अक्सर यह सुनिश्चित करती है कि सही अभिव्यक्ति का मूल्यांकन सही समय पर किया जाता है, अर्थात, परिचालन शब्दार्थ को समझना।
एक ऐसी अभिव्यक्ति जिसका सामान्य रूप खुद कहा जाता है , सामान्य रूप में होती है ।
कुछ अभिव्यक्तियाँ, उदाहरण के let x = 1:x in x
में कोई सामान्य रूप नहीं है, लेकिन अभी भी उत्पादक हैं। उदाहरण अभिव्यक्ति का अभी भी एक मूल्य है , अगर कोई अनंत मूल्यों को स्वीकार करता है, जो यहां सूची [1,1, ...]
। अन्य अभिव्यक्तियाँ, जैसे let y = 1+y in y
का कोई मूल्य नहीं है, या उनका मान undefined
।
कमजोर सिर सामान्य रूप
RNF एक अभिव्यक्ति का पूरी तरह से मूल्यांकन करने के लिए मेल खाती है - इसी तरह, कमजोर सिर सामान्य रूप (WHNF) अभिव्यक्ति के प्रमुख के मूल्यांकन के अनुरूप है। एक अभिव्यक्ति e
सिर का पूरी तरह से मूल्यांकन किया जाता है यदि e
एक एप्लिकेशन Con e1 e2 .. en
और Con
एक निर्माता है; या एक अमूर्त \x -> e1
; या एक आंशिक अनुप्रयोग f e1 e2 .. en
, जहां आंशिक अनुप्रयोग का अर्थ है f
n
तर्क से अधिक लेता है (या समकक्ष, e
का प्रकार एक फ़ंक्शन प्रकार है)। किसी भी स्थिति में, e1..en
होने वाले अभिव्यक्ति के लिए सब-एक्सपेर्सेशन e1..en का मूल्यांकन या मूल्यांकन नहीं किया जा सकता है - वे भी undefined
हो सकते हैं।
हास्केल के मूल्यांकन शब्दार्थ को WHNF के संदर्भ में वर्णित किया जा सकता है - एक अभिव्यक्ति e
मूल्यांकन करने के लिए, पहले इसका मूल्यांकन WHNF के लिए करें, फिर इसके सभी उप-संदर्भों का बाईं से दाईं ओर पुनर्मूल्यांकन करें।
WHNF की अभिव्यक्ति का मूल्यांकन करने के लिए आदिम seq
फ़ंक्शन का उपयोग किया जाता है। seq xy
, denotationally to y
बराबर है ( seq xy
का मूल्य ठीक y
); इसके बाद x
का मूल्यांकन WHNF से किया जाता है जब y
का मूल्यांकन WHNF से किया जाता है। WHNF के लिए एक धमाकेदार पैटर्न के साथ एक अभिव्यक्ति का मूल्यांकन भी किया जा सकता है ( -XBangPatterns
एक्सटेंशन द्वारा सक्षम), जिसका सिंटैक्स निम्नानुसार है:
f !x y = ...
जिसमें x
का मूल्यांकन डब्ल्यूएचएनएफ से किया जाएगा जब f
का मूल्यांकन किया जाता है, जबकि y
का मूल्यांकन नहीं किया जाता है (आवश्यक)। एक कंस्ट्रक्टर में एक बैंग पैटर्न भी दिखाई दे सकता है, जैसे
data X = Con A !B C .. N
जिस स्थिति में कंस्ट्रक्टर Con
को B
क्षेत्र में सख्त कहा जाता है, जिसका अर्थ है कि B
क्षेत्र का मूल्यांकन डब्ल्यूएचएनएफ के लिए किया जाता है जब कंस्ट्रक्टर को पर्याप्त (यहां, दो) तर्कों पर लागू किया जाता है।
आलसी पैटर्न
आलसी, या अकाट्य , पैटर्न (वाक्यविन्यास ~pat
साथ चिह्नित) ऐसे पैटर्न हैं जो हमेशा मेल खाते हैं, यहां तक कि मिलान किए गए मूल्य को भी देखे बिना। इसका मतलब है कि आलसी पैटर्न नीचे के मूल्यों से भी मेल खाएगा। हालांकि, एक अकाट्य पैटर्न के उप-पैटर्न में बंधे चर के बाद के उपयोग मैच के सफल होने तक नीचे का मूल्यांकन करने के लिए मिलान करने के लिए पैटर्न को मजबूर करेंगे।
निम्न कार्य अपने तर्क में आलसी है:
f1 :: Either e Int -> Int
f1 ~(Right 1) = 42
और इसलिए हम प्राप्त करते हैं
λ» f1 (Right 1)
42
λ» f1 (Right 2)
42
λ» f1 (Left "foo")
42
λ» f1 (error "oops!")
42
λ» f1 "oops!"
*** type mismatch ***
निम्नलिखित फ़ंक्शन एक आलसी पैटर्न के साथ लिखा गया है, लेकिन वास्तव में पैटर्न के चर का उपयोग कर रहा है जो मैच को मजबूर करता है, इसलिए Left
तर्कों के लिए असफल होगा:
f2 :: Either e Int -> Int
f2 ~(Right x) = x + 1
λ» f2 (Right 1)
2
λ» f2 (Right 2)
3
λ» f2 (Right (error "oops!"))
*** Exception: oops!
λ» f2 (Left "foo")
*** Exception: lazypat.hs:5:1-21: Irrefutable pattern failed for pattern (Right x)
λ» f2 (error "oops!")
*** Exception: oops!
let
बाइंडिंग, आलसी हैं अकाट्य पैटर्न के रूप में व्यवहार करते हैं:
act1 :: IO ()
act1 = do
ss <- readLn
let [s1, s2] = ss :: [String]
putStrLn "Done"
act2 :: IO ()
act2 = do
ss <- readLn
let [s1, s2] = ss
putStrLn s1
यहाँ act1
आदानों पर काम करता है कि तार के किसी भी सूची, को पार्स जबकि में act2
putStrLn s1
जरूरतों का मूल्य s1
जो बलों के लिए पैटर्न मिलान [s1, s2]
, तो यह केवल ठीक दो तार की सूचियों के लिए काम करता है:
λ» act1
> ["foo"]
Done
λ» act2
> ["foo"]
*** readIO: no parse ***
कड़े खेत
एक data
घोषणा में, एक धमाके के साथ एक प्रकार का उपसर्ग ( !
) क्षेत्र को एक सख्त क्षेत्र बनाता है। जब डेटा कंस्ट्रक्टर लागू किया जाता है, तो उन क्षेत्रों का मूल्यांकन कमजोर सिर सामान्य रूप में किया जाएगा, इसलिए फ़ील्ड में डेटा को हमेशा कमजोर सिर सामान्य रूप में रहने की गारंटी है।
सख्त फ़ील्ड का उपयोग रिकॉर्ड और गैर-रिकॉर्ड दोनों प्रकारों में किया जा सकता है:
data User = User
{ identifier :: !Int
, firstName :: !Text
, lastName :: !Text
}
data T = MkT !Int !Int