मुझे लगता है कि मैंने इसे किसी समय पर हास्केल-कैफे पर पूछा होगा, लेकिन अगर मैं अब जवाब पा सकता हूं तो शापित हो गया ... इसलिए मैं इसे फिर से पूछ रहा हूं, इसलिए उम्मीद है कि भविष्य में मैं कर सकता हूं उत्तर उत्तर मिला!एसोसिएटेड प्रकार और कंटेनर तत्व
पैरास्केट्रिक पॉलिमॉर्फिज्म से निपटने पर हास्केल शानदार है। लेकिन मुसीबत यह है कि सब कुछ पैरामीट्रिक नहीं है। एक मामूली उदाहरण के रूप में, मान लें कि हम डेटा के पहले तत्व को कंटेनर से बाहर ले जाना चाहते हैं। एक पैरामीट्रिक प्रकार के लिए, कि तुच्छ है:
class HasFirst c where first :: c x -> Maybe x instance HasFirst [] where first [] = Nothing first (x:_) = Just x
अब कोशिश करते हैं और ByteString
के लिए एक उदाहरण के बारे में। आप नहीं कर सकते इसका प्रकार तत्व प्रकार का उल्लेख नहीं करता है। आप Set
के लिए एक उदाहरण भी नहीं लिख सकते हैं, क्योंकि इसे Ord
बाधा की आवश्यकता होती है - लेकिन क्लास हेड तत्व प्रकार का उल्लेख नहीं करता है, इसलिए आप इसे बाधित नहीं कर सकते हैं।
एसोसिएटेड प्रकार एक साफ रास्ता पूरी तरह से इन समस्याओं को ठीक करने के लिए प्रदान करते हैं:
class HasFirst c where type Element c :: * first :: c -> Maybe (Element c) instance HasFirst [x] where type Element [x] = x first [] = Nothing first (x:_) = Just x instance HasFirst ByteString where type Element ByteString = Word8 first b = b ! 0 instance Ord x => HasFirst (Set x) where type Element (Set x) = x first s = findMin s
हम अब एक नई समस्या है, लेकिन। Functor
इतना है कि यह सभी कंटेनर प्रकार के लिए काम करता है "ठीक" करने की कोशिश कर विचार करें:
class Functor f where type Element f :: * fmap :: (Functor f2) => (Element f -> Element f2) -> f -> f2
यह सब पर काम नहीं करता। यह कहता है कि यदि हमारे पास f
के तत्व प्रकार f2
के तत्व प्रकार से कोई फ़ंक्शन है, तो हम f
को f2
में बदल सकते हैं। अब तक सब ठीक है। हालांकि, स्पष्ट रूप से कोई रास्ता है कि f
और f2
समान प्रकार के कंटेनर हैं!
के तहत मौजूदा Functor
परिभाषा, हम
fmap :: (x -> y) -> [x] -> [y] fmap :: (x -> y) -> Seq x -> Seq y fmap :: (x -> y) -> IO x -> IO y
है लेकिन हम नहींfmap :: (x -> y) -> IO x -> [y]
है। यह काफी असंभव है। लेकिन उपरोक्त वर्ग परिभाषा इसे अनुमति देता है।
क्या कोई जानता है कि टाइप सिस्टम को कैसे समझाया जाए, मैं वास्तव में का मतलब था?
संपादित
एक कंटेनर प्रकार से एक तत्व प्रकार गणना करने के लिए एक तरह से परिभाषित करते हुए ऊपर काम करता है। क्या होता है यदि आप इसे दूसरी तरफ करने की कोशिश करते हैं? किसी तत्व प्रकार से कंटेनर प्रकार की गणना करने के लिए फ़ंक्शन को परिभाषित करें? क्या यह किसी भी काम से बाहर काम करता है?
अभी भी यह समझने के लिए संघर्ष कर रहा है कि यहां क्या हो रहा है ... तर्कसंगत, यह आसान है। हम एक नक्शा फ़ंक्शन चाहते हैं जो किसी भी कानूनी इनपुट प्रकार को स्वीकार करता है, और किसी भी कानूनी आउटपुट प्रकार का उत्पादन करता है। मुश्किल हिस्सा परिभाषित कर रहा है कि किसी दिए गए कंटेनर के लिए कौन से प्रकार "कानूनी" हैं। (मैं इस पूरे "कठोर" बनाम "पैरामीट्रिक" भेद में नहीं हूं।) क्या कोई समझा सकता है कि सभी "~" अक्षर क्या हैं? या क्या "बाधा" का मतलब है? – MathematicalOrchid
मैंने उम्मीदों को बेहतर ढंग से समझाने के लिए अपना उत्तर विस्तारित किया है; मैं 'पोस्ट्रेन' की अधिक विस्तृत व्याख्या के लिए लिंक किए गए ब्लॉग पोस्ट को पढ़ने की भी सिफारिश करता हूं। – ehird
तो दयालु "*" एक सामान्य प्रकार है, दयालु "* -> *" किसी भी प्रकार का कन्स्ट्रक्टर है, और दयालु "बाधा" बिल्कुल एक प्रकार नहीं है, यह एक प्रकार की बाधा है? क्या वह सही है? – MathematicalOrchid