या विशिष्ट होने के लिए, हम संख्याओं को एन्कोड करने के लिए सूचियों और पुनरावृत्ति को एन्कोड करने के लिए फ़ोल्डर का उपयोग क्यों करते हैं?हम डेटाटाइप को फ़ंक्शन के रूप में एन्कोड करने के लिए फ़ोल्डर्स का उपयोग क्यों करते हैं?
लंबे समय से परिचय के लिए खेद है, लेकिन मुझे वास्तव में उन चीज़ों का नाम कैसे देना है जिन्हें मैं पूछना चाहता हूं, इसलिए मुझे पहले कुछ एक्सपोज़िशन देना होगा। यह this C.A.McCann post से भारी रूप से आकर्षित करता है जो मेरी जिज्ञासा को पूरी तरह संतुष्ट नहीं करता है और मैं रैंक-एन-प्रकारों और अनंत आलसी चीजों के साथ मुद्दों को भी हाथ से रखूंगा।
एक तरह से काम करता है के रूप में डेटाटाइप्स एन्कोड करने के लिए एक "पैटर्न मिलान" समारोह है कि प्रत्येक मामले के लिए एक तर्क प्राप्त करता है बनाने के लिए है, प्रत्येक तर्क एक समारोह है कि मूल्यों कि निर्माता के लिए इसी और सभी तर्कों एक लौटा दिया प्राप्त करता जा रहा है परिणाम प्रकार।
यह सभी के रूप में गैर पुनरावर्ती प्रकार
--encoding data Bool = true | False
type Bool r = r -> r -> r
true :: Bool r
true = \ct cf -> ct
false :: Bool r
false = \ct cf -> cf
--encoding data Either a b = Left a | Right b
type Either a b r = (a -> r) -> (b -> r) -> r
left :: a -> Either a b r
left x = \cl cr -> cl x
right :: b -> Either a b r
right y = \cl cr -> cr y
हालांकि, पुनरावर्ती प्रकार के साथ नीचे पैटर्न मिलान टूट के साथ अच्छा सादृश्य के लिए उम्मीद बाहर काम करता है। हम जैसे
--encoding data Nat = Z | S Nat
type RecNat r = r -> (RecNat -> r) -> r
zero = \cz cs -> cz
succ n = \cz cs -> cs n
-- encoding data List a = Nil | Cons a (List a)
type RecListType a r = r -> (a -> RecListType -> r) -> r
nil = \cnil ccons -> cnil
cons x xs = \cnil ccons -> ccons x xs
कुछ करने के लिए परीक्षा हो सकती है, लेकिन हम हास्केल में उन पुनरावर्ती प्रकार परिभाषाएं नहीं लिख सकते हैं! सामान्य समाधान केवल पहले व्यक्ति (यानी, एक गुना/इटरेटर लिखना) की बजाय पुनरावृत्ति के सभी स्तरों पर लागू होने के लिए विपक्ष/succ मामले के कॉलबैक को लागू करना है। इस संस्करण में हम वापसी प्रकार r
जहां पुनरावर्ती प्रकार होगा का उपयोग करें: इस संस्करण से काम करता है
--encoding data Nat = Z | S Nat
type Nat r = r -> (r -> r) -> r
zero = \cz cf -> cz
succ n = \cz cf -> cf (n cz cf)
-- encoding data List a = Nil | Cons a (List a)
type recListType a r = r -> (a -> r -> r) -> r
nil = \z f -> z
cons x xs = \z f -> f x (xs z f)
, यह बहुत कठिन कुछ कार्यों को परिभाषित करता है। उदाहरण के लिए, सूचियों के लिए "पूंछ" फ़ंक्शन या संख्याओं के लिए "पूर्ववर्ती" फ़ंक्शन लिखना मामूली है यदि आप पैटर्न मिलान का उपयोग कर सकते हैं लेकिन यदि आपको इसके बजाय फ़ोल्डरों का उपयोग करने की आवश्यकता है तो मुश्किल हो जाती है।
तो मेरा असली सवाल पर:
हम कैसे सुनिश्चित करें कि परतों का उपयोग कर एन्कोडिंग काल्पनिक "एन्कोडिंग मिलान पैटर्न" के रूप में के रूप में शक्तिशाली है हो सकता है? क्या पैटर्न मिलान के माध्यम से मनमाने ढंग से कार्य परिभाषा लेने का कोई तरीका है और यांत्रिक रूप से इसके बजाय केवल फ़ोल्डरों का उपयोग करके इसे परिवर्तित कर सकते हैं? (यदि ऐसा है, तो यह कम जादुई के रूप में फ़ोल्डर के मामले में पूंछ या फोल्डल जैसी कठोर परिभाषाओं में मदद करेगा)
हास्केल प्रकार प्रणाली "पैटर्न मिलान" में आवश्यक रिकर्सिव प्रकारों की अनुमति क्यों नहीं देती है एन्कोडिंग?। क्या
data
के माध्यम से परिभाषित डेटाटाइप में रिकर्सिव प्रकारों को केवल अनुमति देने का कोई कारण है? क्या पैटर्न सीधे पुनरावर्ती बीजगणित डेटाटाइप का उपभोग करने के लिए एकमात्र तरीका है? क्या इसे एल्गोरिदम के प्रकार के संदर्भ में करना है?
मैं इसे यहां छोड़ दूंगा: http://www.haskell.org/pipermail/haskell-cafe/2010-November/085897.html – melpomene
@melpomene: हम्म, ऐसा लगता है जैसे यह प्रश्न # 2 - आप हास्केल में ऐसा कर सकते हैं लेकिन आपको रिकर्सिविटी तक पहुंच प्राप्त करने के लिए नए प्रकार का उपयोग करने की आवश्यकता है। अब मुझे केवल यह देखने की ज़रूरत है कि क्या आपके द्वारा लिंक किए गए कागजात भी qustion # 1 का जवाब देते हैं :) (बीटीडब्ल्यू, आपका [लिंक] (http://www.haskell.org/pipermail/haskell-cafe/2010-November/085897.html) कॉपी अजीब चिपकाया गया था) – hugomg
हालांकि नेट के लिए पूर्ववर्ती कठिन है, लेकिन 'ओ (1) 'जोड़ना (मुझे लगता है कि आमतौर पर बाइनरी संस्करण कंप्यूटरों की तुलना में यह और भी अधिक कुशल है।) – PyRulez