haskell - यह समझना कि फनकार का एक उदाहरण है




typeclass functor (3)

अपने खाली समय में मैं हास्केल सीख रहा हूं, इसलिए यह एक शुरुआती सवाल है।

मेरी रीडिंग में मुझे एक उदाहरण सामने आया है जिसमें बताया गया है कि किस तरह से Functor का एक उदाहरण बनाया गया है:

instance Functor (Either a) where
    fmap f (Right x) = Right (f x)
    fmap f (Left x) = Left x

अब, मैं यह समझने की कोशिश कर रहा हूं कि Right वैल्यू कंस्ट्रक्टर के मामले में कार्यान्वयन मैप क्यों होता है, लेकिन Left के मामले में नहीं है?

यहाँ मेरी समझ है:

पहले मुझे उपरोक्त उदाहरण के रूप में फिर से लिखना

instance Functor (Either a) where
    fmap g (Right x) = Right (g x)
    fmap g (Left x) = Left x

अभी व:

  1. मुझे पता है कि fmap :: (c -> d) -> fc -> fd

  2. अगर हम Either a साथ f विकल्प देते हैं तो हमें fmap :: (c -> d) -> Either ac -> Either ad

  3. Right (gx) का प्रकार Either a (gx) , और gx का प्रकार d , इसलिए हमारे पास है कि Right (gx) का प्रकार Either ad , जिसे हम fmap से उम्मीद fmap (देखें 2. ऊपर)

  4. अब, यदि हम Left (gx) देखते हैं, तो हम यह कहने के लिए एक ही तर्क का उपयोग कर सकते हैं कि इसका प्रकार Either (gx) b , Either db , जो हम fmap से उम्मीद नहीं fmap (देखें 2. ऊपर): d दूसरा पैरामीटर होना चाहिए, पहला नहीं! इसलिए हम Left नक्शा नहीं बना सकते।

क्या मेरा तर्क सही है?


अब, मैं यह समझने की कोशिश कर रहा हूं कि राइट वैल्यू कंस्ट्रक्टर के मामले में कार्यान्वयन मैप क्यों होता है, लेकिन लेफ्ट के मामले में नहीं है?

यहाँ प्लग करें और यह समझ में आ सकता है।

मान लें = स्ट्रिंग (एक त्रुटि संदेश) आप या तो एक फ़्लोट में लागू होते हैं।

तो आपके पास एक एफ: फ्लोट -> इंटेगर उदाहरण के लिए राउंडऑफ कहते हैं।

(या तो स्ट्रिंग) (फ्लोट) = या तो स्ट्रिंग फ्लोट।

अब (fmap f) :: या तो स्ट्रिंग फ्लोट -> या तो स्ट्रिंग इंट तो आप एफ के साथ क्या करने जा रहे हैं? f के पास कोई सुराग नहीं है कि आप स्ट्रिंग्स के साथ क्या करें ताकि आप वहां कुछ भी न कर सकें। यह स्पष्ट रूप से केवल एक चीज है जिस पर आप कार्य कर सकते हैं, जबकि बाएं मूल्यों को अपरिवर्तित रखते हुए सही मान हैं।

दूसरे शब्दों में, या तो एक फ़नकार है क्योंकि इस तरह का एक स्पष्ट फमा है:

  • सही मानों के लिए एफ लागू करें
  • वामपंथी मूल्यों के लिए कुछ नहीं करते

आपका खाता सही है। हो सकता है कि इस तरह के उदाहरणों के कारण हमें कठिनाई हो रही है कि हम वास्तव में एक ही बार में कई मज़ेदार उदाहरणों को परिभाषित कर रहे हैं - प्रत्येक संभावित Left प्रकार के लिए। लेकिन एक फनकार उदाहरण सिस्टम में असीम रूप से कई प्रकारों पर काम करने का एक व्यवस्थित तरीका है। इसलिए हम असीम रूप से सिस्टम में असीम रूप से कई प्रकारों के ऑपरेटिंग तरीके को परिभाषित कर रहे हैं। उदाहरण में दो तरीकों से सामान्यता शामिल है।

यदि आप इसे चरणों से लेते हैं, हालांकि, शायद यह इतना अजीब नहीं है। इन प्रकारों में से पहला यूनिट प्रकार () और इसके एकमात्र वैध मान () का उपयोग करते हुए Maybe एक लंबा संस्करण है।

data MightBe b     = Nope ()    | Yep b
data UnlessError b = Bad String | Good b
data ElseInt b     = Else Int   | Value b

यहाँ हम थक सकते हैं और एक अमूर्त बना सकते हैं:

data Unless a b    = Mere a     | Genuine b

अब हम अपने फनकार के उदाहरणों को, अनपेक्षित रूप से, पहले बहुत कुछ देख रहे हैं जैसे कि Maybe उदाहरण के लिए:

instance Functor MightBe where
  fmap f (Nope ()) = Nope ()   -- compare with Nothing
  fmap f (Yep x)   = Yep (f x) -- compare with Just (f x)

instance Functor UnlessError where
  fmap f (Bad str) = Bad str   -- a more informative Nothing
  fmap f (Good x)  = Good (f x)

instance Functor ElseInt where
  fmap f (Else n) = Else n 
  fmap f (Value b) = Value (f b)

लेकिन, फिर से, क्यों परेशान करते हैं, चलो अमूर्त बनाते हैं:

instance Functor (Unless a) where
  fmap f (Mere a) = Mere a
  fmap f (Genuine x) = Genuine (f x)

Mere a शब्दों को छुआ नहीं गया है, क्योंकि () , String और Int मान को छुआ नहीं गया था।


यह सही है। इस व्यवहार का एक अन्य महत्वपूर्ण कारण यह भी है: आप Either ab को अभिकलन के रूप में सोच सकते हैं, जो सफल हो सकता है और b या त्रुटि संदेश के साथ विफल हो सकता a । (यह भी है, कैसे मोनड उदाहरण काम करता है)। इसलिए यह केवल स्वाभाविक है, कि फ़नकार का उदाहरण Left मूल्यों को नहीं छूएगा, क्योंकि आप अभिकलन पर नक्शा बनाना चाहते हैं, यदि यह विफल रहता है, तो हेरफेर करने के लिए कुछ भी नहीं है।





either