2012-12-23 38 views
7

को कार्यान्वित करने के लिए मैं हाल ही में अनुक्रमित मोनैड को देख रहा हूं (और समझने की कोशिश कर रहा हूं)। मुझे लगता है कि मेरे पास इंडेक्सेड मोनैड की एक शैली के आसपास मेरा सिर है, जैसा कि यहां बताया गया है: A Neighbourhood of Infinity: Beyond Monadsइंडेक्स-कोर स्टाइल अनुक्रमित निरंतरता मोनैड

हालांकि, मुझे index-core में अनुक्रमित मोनैड की एक अलग शैली मिली है, जिसमें कुछ इंडेक्स हैं जो इस अनुक्रमित मोनैड से मेल खाते हैं, उदाहरण के लिए एक समान बाइंड ऑपरेटर !>=। हालांकि यह स्पष्ट रूप से इंडेक्स में समान परिवर्तन करता है, लेकिन मैं समझ नहीं पा रहा हूं कि इन इंडेक्स का उपयोग कैसे करें, उदाहरण के लिए, दूसरी शैली के साथ निरंतर मोनैड में रिटर्न प्रकारों को नियंत्रित करने के लिए। मुझे अनुक्रमित मोनैड की इस शैली में दिलचस्पी होगी, मुख्य रूप से क्योंकि यह मोनैड ट्रांसफार्मर के लिए बहुत बेहतर काम करता है - असल में मैंने अन्य शैली में परिभाषित एक अनुक्रमित मोनैड ट्रांसफॉर्मर (अनुक्रमित मोनैड का) नहीं देखा है, केवल एक अनुक्रमित ट्रांसफार्मर नियमित monads।

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

+0

एक समान प्रश्न भी देखें: http://stackoverflow.com/questions/23887237/how-to-implement-index-core-style-indexed-state-monad –

उत्तर

10

मैं index-core पैकेज का लेखक हूं, और जवाब यह है कि आप कर सकते हैं।

{-# LANGUAGE TypeOperators, RankNTypes #-} 

import Control.Category.Index 
import Control.IMonad 
import Data.Functor.Identity 

newtype ICont f a i = ICont { runICont :: (a :-> f) -> f i } 

ध्यान दें कि मैं r के बजाय f का उपयोग: यहाँ समाधान है। r एस सूचकांक होने जा रहे हैं।

IFunctor और IMonad के कार्यान्वयन साधारण इकाई (बस ब्लॉग पोस्ट के संस्करण की तरह) के कार्यान्वयन के लिए समान हैं:

instance IFunctor (ICont f) where 
    fmapI f m = bindI (returnI . f) m 

instance IMonad (ICont f) where 
    returnI a = ICont $ \k -> k a 
    bindI f m = ICont $ \k -> runICont m $ \a -> runICont (f a) k 

चाल को एहसास है कि यह संस्करण में देखा था करने के लिए कम कर देता है ब्लॉग पोस्ट जब f = Identity

(a -> r2) -> r1 
~ (a -> Identity r2) -> Identity r1 
~ ((a := r2) r2 -> Identity r2) -> Identity r1 
~ ((a := r2) :-> Identity) -> Identity r1 
~ ICont Identity (a := r2) r1 
~ R ICont Identity r1 r2 a 

फर्क सिर्फ इतना अतिरिक्त R और Identity शोर है, जो आप दूर सार यदि आप चाहें तो कर सकते हैं ब्लॉग पोस्ट के संस्करण से मेल करने के लिए: Kleisli Arrows of Outrageous Fortune:

type ICont' r1 r2 a = ICont Identity (a := r2) r1 

यहाँ ICont

-- example ~ (String -> Int) -> Char 
-- example ~ ((String := Int) Int -> Identity Int) -> Identity Char 
example :: ICont' Char Int String 
example = ICont $ \k -> Identity $ 
    case runIdentity (k (V "Hello")) of 
     0 -> 'A' 
     _ -> 'B' 

index-core लाइब्रेरी का उपयोग कर एक समारोह लिखा कोनोर मैकब्राइड के कागज से प्रेरित था का एक उदाहरण है। ध्यान दें कि कॉनॉर के दृष्टिकोण को ब्लॉग पोस्ट में से एक की तुलना में अधिक वर्बोजिटी की आवश्यकता होती है, लेकिन यह अतिरिक्त सुविधाओं को प्रदान करता है जो ब्लॉग पोस्ट में से एक है, मुख्य रूप से उन सूचकांक में अधिक शक्तिशाली जानकारी स्टोर करने की क्षमता में जो अधिक लचीलापन प्रदान करते हैं।

आपके लिए इसका क्या अर्थ है कि यदि आपको उन अतिरिक्त सुविधाओं की आवश्यकता नहीं है तो आपको शायद ब्लॉग पोस्ट में दिखाई देने वाले किसी का उपयोग करना चाहिए। हालांकि, मैं अत्यधिक अनुशंसा करता हूं कि आप कॉनॉर पेपर को पढ़ लें, चाहे आप जो भी चुनते हों, क्योंकि यह वास्तव में एक उत्कृष्ट पेपर है और दिखाता है कि हास्केल की टाइप सिस्टम कितनी शक्तिशाली हो सकती है।

मैंने index-core के लिए किसी भी अनुक्रमित मोनैड को लागू नहीं किया, मुख्य रूप से क्योंकि मैंने लिखा है कि मैंने लाइब्रेरी को एक और लाइब्रेरी के लिए खदान की खरोंच के लिए लिखा है। यदि आप index-core का उपयोग करने वाले ठोस कोड को देखना चाहते हैं, तो pipes पैकेज के संस्करण 2.2.0 को देखें जहां मैंने अनुक्रमित मुक्त मोनैड ट्रांसफॉर्मर को लागू करने के लिए index-core का उपयोग किया था। हालांकि, अब मैं उस प्रकार का अब और उपयोग नहीं करता हूं, हालांकि मैं अभी भी index-core पैकेज बनाए रखता हूं।

यदि आपके कोई अन्य प्रश्न हैं, तो बेझिझक पूछें!

+0

मदद के लिए बहुत बहुत धन्यवाद, मुझे लगता है कि मैं ' अभी इसे अभी प्राप्त करने के बारे में - मुझे जो कुछ याद आया वह यह था कि कोई भी इंडेक्स किए गए फ़ंक्शन का परिणाम बनाने के लिए पहचान फ़ैक्टर की तरह कुछ उपयोग कर सकता था। मैंने एक सरल कॉलसीसी, शिफ्ट और रीसेट को कार्यान्वित करने में कामयाब रहा है। मुझे आश्चर्य है कि यह एक अनुक्रमित मोनड ट्रांसफॉर्मर बनाने के बारे में कैसे होगा? मैंने कुछ नया उपयोग करने की कोशिश की जैसे 'न्यूटाइप आई एम आई = आई (एम (आई: = i) i)' लेकिन मैं काम करने के लिए लिफ्ट नहीं कर सका, क्योंकि सूचकांक bindI में फ़ंक्शन के रिटर्न प्रकार में लीक हो गया था। वैसे भी मदद के लिए धन्यवाद, मैं अकादमिक जिज्ञासा की वजह से काफी हद तक देख रहा हूं। – DarkOtter

+0

हाँ, जहां तक ​​मुझे पता है, इंडेक्स लीकिंग समस्या का कोई अच्छा समाधान नहीं है। मैंने इस बारे में कॉनन को बताया लेकिन उस पर उससे वापस नहीं सुना है। हालांकि, आप इसे सामान्य मोनैड ट्रांसफॉर्मर बना सकते हैं, क्योंकि यदि आप इसे लपेटते हैं तो सामान्य मोनड इंडेक्स को नहीं बदलता है। –

+0

आप दावा कर रहे हैं कि '(a: = r2) r2 -> पहचान r2' '(a: = r2): -> पहचान' जैसा ही है। क्या आप वाकई सही हैं? –