2015-02-21 15 views
11

मैं अक्सर पढ़ता हूं किपहचान मोनड उपयोगी क्यों है?

ऐसा लगता है कि पहचान मोनड बेकार है। यह नहीं है ... लेकिन यह एक और विषय है।

तो क्या कोई मुझे बता सकता है कि यह कैसे उपयोगी है?

+0

मैं monads की व्याख्या करने के लिए एक महान उपकरण के रूप में देखते इस तरह के सामान पर पूर्व ज्ञान वाले लोगों के लिए और किसी भी व्यक्ति के लिए मोनैड को लागू करने के तरीके के बारे में सीखने के लिए एक मूल्यवान अभ्यास के रूप में। – ThreeFx

उत्तर

12

Identity के रूप में 0 नंबर पर है monads, functors और अनुप्रयोगी functors है। अपने आप पर यह बेकार लगता है, लेकिन अक्सर उन जगहों पर इसकी आवश्यकता होती है जहां एक मोनैड या (आवेदक) मज़ेदार की अपेक्षा करता है जो वास्तव में कुछ भी नहीं करता है।

जैसा कि पहले से ही उल्लेख किया गया है, Identity हमें सिर्फ मोनैड ट्रांसफार्मर को परिभाषित करने की अनुमति देता है और फिर SomeT Identity के रूप में उनके संबंधित मोनैड को परिभाषित करता है।

लेकिन यह सब कुछ नहीं है। मोनैड के मामले में अन्य अवधारणाओं को परिभाषित करना अक्सर सुविधाजनक होता है, जो आमतौर पर बहुत लचीलापन जोड़ता है। उदाहरण के लिए Conduit i m o (this tutorial भी देखें) एक पाइपलाइन में एक तत्व को परिभाषित करता है जो i के डेटा का अनुरोध कर सकता है, o प्रकार का डेटा उत्पन्न कर सकता है, और आंतरिक प्रसंस्करण के लिए मोनैड m का उपयोग करता है। तो फिर इस तरह के एक पाइपलाइन

($$) :: Monad m => Source m a -> Sink a m b -> m b 

(जहां Source कोई उत्पादन के साथ Conduit के लिए कोई इनपुट के साथ Conduit और Sink के लिए एक उपनाम है) का उपयोग कर दिया इकाई में चलाया जा सकता है। और जब कोई effectful संगणना पाइप लाइन में की जरूरत है, सिर्फ शुद्ध कोड है, हम बस mIdentity के विशेषज्ञ और इस तरह के एक पाइप लाइन को चलाने के रूप में

runIdentity (source $$ sink) 

Identity भी "खाली" functor और अनुप्रयोगी functor है: Identity एक अन्य मज़ेदार या आवेदक मज़ेदार के साथ बना मूल के लिए isomorphic है।

Functor f => (a -> f a) -> s -> f s 

मोटे तौर पर कहा जाए तो इस तरह के एक लेंस एक परिचय के लिए एक रिकॉर्ड के अंदर एक क्षेत्र (पढ़ने के लिए या प्रकार a के बारे में कुछ हेरफेर s अंदर, उदाहरण के लिए कर सकते हैं: उदाहरण के लिए, Lens' एक Functor में एक समारोह बहुरूपी के रूप में परिभाषित किया गया है लेंस के लिए this post देखें)। अगर हम fIdentity के विशेषज्ञ, हम

(a -> Identity a) -> s -> Identity s 

जो

(a -> a) -> s -> s 

isomorphic को है, इसलिए a पर एक अद्यतन करने समारोह को देखते हुए हो, s पर एक अद्यतन करने फ़ंक्शन रिटर्न। (पूर्णता के लिए: यदि हम fConst a के विशेषज्ञ, हम (a -> Const b a) -> s -> Const b s जो (a -> b) -> (s -> b) isomorphic को है मिलता है,, कि है, a पर एक पाठक को देखते हुए एक पाठक s पर लौट आते हैं।)

3

एक वास्तविक उपयोग-मामला मोनैड ट्रांसफार्मर स्टैक का एक (शुद्ध) आधार होना चाहिए, उदा। इसके बारे में

type Reader r = ReaderT r Identity 
9

एक प्रयोग इकाई ट्रांसफार्मर के ढेर के लिए एक आधार इकाई के रूप में है: बजाय दो प्रकार Some :: * ->* और SomeT :: (* -> *) -> * -> * प्रदान करने के लिए होने के लिए, यह type Some = SomeT Identity की स्थापना करके सिर्फ एक उत्तरार्द्ध प्रदान करने के लिए पर्याप्त है। (a, b, c) एक त्रिगुट टपल है (a, b) एक द्विआधारी टपल है हम कह सकते हैं () एक nullary टपल है,,,:

एक और, कुछ इसी तरह उपयोग के मामले (लेकिन पूरी तरह से पूरे इकाई व्यापार से अलग) जब आप tuples का उल्लेख करने की आवश्यकता है और इसी तरह, लेकिन यह मामूली मामले के लिए क्या छोड़ता है? aa की किसी भी पसंद के लिए एक यूनरी टुपल अक्सर संतोषजनक नहीं है, उदाहरण के लिए जब हम Data.Tuple.Select जैसे कुछ टाइपक्लास उदाहरण बना रहे हैं, तो कुछ प्रकार के कन्स्ट्रक्टर को अस्पष्ट कुंजी के रूप में कार्य करने की आवश्यकता होती है। तो उदा। जोड़कर Identity a को Sel1 उदाहरणों, यह (a, b) (एक दो टपल एक a और एक b युक्त), और Identity (a, b) (एक-टपल एक भी (a, b) मूल्य युक्त) के बीच अंतर करने के लिए हमें बाध्य करती है।

(ध्यान दें कि Data.Tuple.Select अपना अलग प्रकार के बजाय Identity पुन: उपयोग की OneTuple कहा जाता है को परिभाषित करता है, लेकिन यह Identity -इन तथ्य isomorphic को है, यह सिर्फ एक नाम बदलने दूर-और मुझे लगता है कि यह केवल एक गैर base निर्भरता से बचने के लिए मौजूद है।)

+1

'पहचान' 4.8 में आधार में शामिल हो रही है, इसलिए यह जल्द ही एक ऐतिहासिक आर्टिफैक्ट हो सकता है। इन तरीकों से 'डेटा सिक्योरेंस' एक आंतरिक 'एलेम' प्रकार ('पहचान' के लिए आइसोमोर्फिक) का भी उपयोग करता है। – dfeuer

11

कभी-कभी मैं रिकॉर्ड के साथ काम करता हूं जिनके फ़ील्ड कुछ संदर्भों में वैकल्पिक हैं (जैसे जेएसओएन से रिकॉर्ड पार्स करते समय) लेकिन दूसरों में अनिवार्य है।

मैं हल करता हूं कि एक मज़ेदार के साथ रिकॉर्ड को पैरामीट्रिजिंग करके, और प्रत्येक मामले में Maybe या Identity का उपयोग करके हल करें।

{-# LANGUAGE DeriveGeneriC#-} 
{-# LANGUAGE StandaloneDeriving #-} 

data Query f = Query 
    { 
     _viewName :: String 
    , _target :: f Server -- Server is some type, it doesn't matter which 
    } 
    deriving (Generic) 

सर्वर फ़ील्ड वैकल्पिक जब JSON को पार्स है:

instance FromJSON (Query Maybe) 

लेकिन फिर मैं की तरह

withDefaultServer :: Server -> Query Maybe -> Query Identity 
withDefaultServer = undefined 

कि एक रिकार्ड है, जिसमें _target फील्ड अनिवार्य है देता है एक समारोह है।

(इस उत्तर के लिए कुछ भी Identity के बारे में monadic, हालांकि उपयोग नहीं करता।)

संबंधित मुद्दे