2011-09-14 10 views
5

के रूप में मोनैड संरचना को सारण करना क्षमा करें यदि प्रश्न थोड़ा सा मामूली लगता है ... यह मेरे लिए नहीं है।ट्रांसफॉर्मर

type SB i a = ReaderT (AlgRO i) (State (AlgState i)) a 

जो है, ठीक है, एक अच्छी तरह से व्यवहार किया इकाई: मैं खुशी से निम्नलिखित इकाई बना दिया है। रीडर टी एक मोनड ट्रांसफार्मर है और राज्य राज्य मोनड है, और अल्ग्रो और अल्गस्टेट क्रमशः उत्परिवर्तनीय और केवल पढ़ने के लिए राज्य में पैराटाइप्स पैरामीटर है। अब, अगर मुझे लगता है कि newtype के साथ एक साफ इकाई ट्रांसफार्मर, कुछ इस तरह का बनाना चाहते:

newtype SbT m i a = SbT { 
    runSbT:: m (SB i a) 
} 

मैं कैसे आगे बढ़ना चाहिए? मैं बाइंड विधि (मोनाड टाइपक्लास) के बहुत कम "लिफ्ट" (मोनाडट्रान्स) को एक साथ रखने का प्रबंधन भी नहीं कर सकता ... मुझे लगता है कि स्वचालित व्युत्पन्न मदद कर सकता है, लेकिन मैं समझना चाहता हूं कि यह इस मामले में कैसे काम करता है।

अग्रिम धन्यवाद।

उत्तर

10

मुझे नहीं लगता कि SbT के लिए परिभाषा आप चाहते हैं। यह फ़ैक्टर संरचना परिभाषित करता है, और m पैरामीटर मानता है Functor या Applicative, यह उन गुणों को संरक्षित रखना चाहिए। लेकिन इस तरह की रचना सामान्य रूप से दो अन्य लोगों में से एक नया मोनड नहीं बनाती है। उस विषय पर अधिक के लिए this question देखें।

तो, क्या आप चाहते हैं कि मोनैड ट्रांसफॉर्मर बनाएं, फिर? जबकि monads सीधे लिख नहीं है, monad ट्रांसफॉर्मर बनाया जा सकता है। तो मौजूदा लोगों में से एक नया ट्रांसफार्मर बनाने के लिए, आप अनिवार्य रूप से बस उस रचना को एक नाम देना चाहते हैं। यह newtype से अलग है क्योंकि आपके पास ट्रांसफॉर्मर स्टैक में इसे पास करने के बजाय सीधे m लागू कर रहे हैं।

मोनैड ट्रांसफार्मर को परिभाषित करने के बारे में ध्यान में रखना एक बात यह है कि जब आप एक मोनाड में एक समग्र ट्रांसफॉर्मर लागू करते हैं, तो "अनिवार्य" ट्रांसफॉर्मर को पहली क्रैक मिलती है, और वे कुछ तरीकों से "पिछड़ा" काम करते हैं, और " यह परिवर्तित मोनाड है जो अगले ट्रांसफॉर्मर के साथ काम करने के लिए मिलता है, & सी। ध्यान दें कि किसी तर्क के लिए एक रचनात्मक फ़ंक्शन को लागू करते समय आपको प्राप्त होने वाले आदेश से यह कोई अलग नहीं है, उदा। (f . g . h) xh पर तर्क देता है, भले ही f संरचना में "पहला" फ़ंक्शन है।

ठीक है, तो अपने समग्र ट्रांसफार्मर इकाई यह पर लागू की गई लेते हैं और इसे अंतरतम ट्रांसफार्मर, जो है, uhm .... उफ़, पता चला है कि SBपहले से ही एक इकाई के लिए आवेदन किया है करने के लिए पारित करने के लिए की जरूरत है। कोई आश्चर्य नहीं कि यह काम नहीं कर रहा था। हमें पहले इसे हटाने की आवश्यकता होगी। कहाँ है? State - हम हटा सकते हैं, लेकिन हम नहीं चाहते हैं, क्योंकि यह आप चाहते हैं कि यह हिस्सा है। हम्म, लेकिन प्रतीक्षा करें - State क्या है, फिर से परिभाषित किया गया है? ओह, हाँ:

type State s = StateT s Identity 

अहा, वहाँ हम चले। आइए वहां से Identity प्राप्त करें।

type SB i a = ReaderT (AlgRO i) (StateT (AlgState i) Identity) a 

फिर हम आलसी बम बाहर निकाल:

type SB' i m a = ReaderT (AlgRO i) (StateT (AlgState i) m) a 
type SB i a = SB' i Identity a 

लेकिन अब SB' एक इकाई ट्रांसफार्मर की तरह संदेह से लग रहा है

type SB i a = ReaderT (AlgRO i) (State (AlgState i)) a 
बराबर प्रपत्र के लिए

: हम अपने वर्तमान परिभाषा से जाना परिभाषा, और अच्छे कारण से, क्योंकि यह है। इसलिए हम newtype आवरण पुन: बनाने, और वहाँ कुछ उदाहरणों टॉस:

newtype SbT i m a = SbT { getSB :: ReaderT (AlgRO i) (StateT (AlgState i) m) a } 

instance (Functor m) => Functor (SbT i m) where 
    fmap f (SbT sb) = SbT (fmap f sb) 

instance (Monad m) => Monad (SbT i m) where 
    return x = SbT (return x) 
    SbT m >>= k = SbT (m >>= (getSB . k)) 

instance MonadTrans (SbT i) where 
    lift = SbT . lift . lift 

runSbT :: SbT i m a -> AlgRO i -> AlgState i -> m (a, AlgState t) 
runSbT (SbT m) e s = runStateT (runReaderT m e) s 

कुछ बातें ध्यान देने के लिए: यहाँ runSbT समारोह क्षेत्र एक्सेसर प्रत्येक के लिए एक रचना "रन" समारोह नहीं है, बल्कि ट्रांसफॉर्मर जो ढेर में हम जानते हैं। इसी प्रकार, lift फ़ंक्शन को दो आंतरिक ट्रांसफार्मर के लिए एक बार उठाना होता है, फिर अंतिम newtype रैपर जोड़ें। इनमें से दोनों इसे एक मोनैड ट्रांसफॉर्मर के रूप में काम करते हैं, इस तथ्य को छिपाते हुए कि यह वास्तव में एक समग्र है।

यदि आप चाहें, तो यह MonadReader और MonadState के लिए उदाहरण लिखने के लिए सरल होना चाहिए, साथ ही रचनाकृत ट्रांसफॉर्मर के उदाहरणों को उठाकर।

+0

कि यह नहीं होगा। धन्यवाद! – dsign

2

क्या आप अपने नए टाइप में चीजों के आस-पास एक अतिरिक्त m लपेटना चाहते थे? मैं निम्नलिखित सुझाव है:

newtype Sb i a = Sb { runSb :: SB i a } 

... जो अपने instance Monad (Sb i) थोड़ा आसान लिखने के लिए करना चाहिए। यदि आप वास्तव में एक मोनड ट्रांसफॉर्मर लिखने की कोशिश कर रहे हैं, तो आपको ट्रांसफॉर्मर का उपयोग सभी तरह से करना चाहिए; उदाहरण के लिए,

type SBT m i a = ReaderT (AlgRO i) (StateT (AlgState i) m) a 
newtype SbT m i a = SbT { runSbT :: SBT m i a } 

ब्याज की एक दूसरी बात के रूप में, यह अक्सर बेहतर type समानार्थी शब्द η-कम करने के लिए (क्योंकि वे हमेशा "पूरी तरह से लागू" होना चाहिए) है, SB और SBT के साथ ऐसा करने इस प्रकार दिखाई देगा:

type SB i = ReaderT (AlgRO i) (State (AlgState i)) 
type SBT m i = ReaderT (AlgRO i) (StateT (AlgState i) m) 
+0

वैसे, आप इस तरह से 'एसबीटी' से एक मोनाड ट्रांसफार्मर नहीं बना सकते हैं। ट्रांसफॉर्मर्स के पास दयालु '(* -> *) -> * -> *', यानी, एक मोनैड और एक प्रकार के तर्क के रूप में लेना है। 'I' पैरामीटर पहले होना चाहिए, इसलिए आप आंशिक रूप से इसे लागू कर सकते हैं। –

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

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