हमेशा की तरह, शब्दावली लोगों का उपयोग पूरी तरह से संगत नहीं है। कई तरह के प्रेरित-से-मोनड्स हैं, लेकिन कड़ाई से बोलने वाले-काफी-विचार नहीं हैं। शब्द "अनुक्रमित मोनाड" एक संख्या में से एक है (जिसमें "मोनडिश" और "पैरामीटराइज़्ड मोनड" (उनके लिए एटिक्स का नाम)) एक ऐसी धारणा की विशेषता है। (एक अन्य ऐसी धारणा, यदि आप रुचि रखते हैं, तो कतसुमता का "पैरामीट्रिक प्रभाव मोनाड" है, जो एक मोनॉइड द्वारा अनुक्रमित होता है, जहां रिटर्न न्यूट्रल रूप से अनुक्रमित होता है और इसके सूचकांक में बाँध होता है।)
सबसे पहले, चलो प्रकार की जांच करते हैं।
IxMonad (m :: state -> state -> * -> *)
यही है, "गणना" (या "कार्रवाई" का प्रकार, यदि आप चाहें, लेकिन मैं "गणना" के साथ चिपका रहूँगा), जैसा दिखता है
m before after value
जहां before, after :: state
और value :: *
। यह विचार एक बाहरी प्रणाली के साथ सुरक्षित रूप से बातचीत करने के साधनों को पकड़ने के लिए है जिसमें राज्य की कुछ पूर्वानुमानित धारणा है। एक संगणना का प्रकार आपको बताता है कि राज्य को क्या होना चाहिए before
, राज्य क्या होगा after
और यह *
किस प्रकार चलता है (जैसे नियमित साधुओं के साथ ) value
संगणना किस प्रकार का उत्पादन करती है।
सामान्य बिट्स और टुकड़े *
एक state
मोनाड की तरह- और डोमिनोज़ खेलने की तरह -वाइज़ होते हैं।
ireturn :: a -> m i i a -- returning a pure value preserves state
ibind :: m i j a -> -- we can go from i to j and get an a, thence
(a -> m j k b) -- we can go from j to k and get a b, therefore
-> m i k b -- we can indeed go from i to k and get a b
इस तरह से उत्पन्न "क्लेइसली तीर" (फ़ंक्शन जो गणना की उपज देता है) की धारणा है
a -> m i j b -- values a in, b out; state transition i to j
और हमें एक रचना मिलती है
icomp :: IxMonad m => (b -> m j k c) -> (a -> m i j b) -> a -> m i k c
icomp f g = \ a -> ibind (g a) f
और, हमेशा की तरह, कानून वास्तव में यह सुनिश्चित करते हैं ireturn
और icomp
हमें एक श्रेणी देते हैं
ireturn `icomp` g = g
f `icomp` ireturn = f
(f `icomp` g) `icomp` h = f `icomp` (g `icomp` h)
या, कॉमेडी में नकली सी / जावा / जो भी हो,
g(); skip = g()
skip; f() = f()
{g(); h()}; f() = h(); {g(); f()}
क्यों परेशान? बातचीत के "नियम" को लागू करने के लिए। उदाहरण के लिए, यदि आप ड्राइव में एक नहीं हैं, तो आप एक डीवीडी को नहीं निकाल सकते हैं, और यदि आप पहले से ही इसमें मौजूद हैं तो आप डीवीडी को ड्राइव में नहीं डाल सकते। इसलिए
data DVDDrive :: Bool -> Bool -> * -> * where -- Bool is "drive full?"
DReturn :: a -> DVDDrive i i a
DInsert :: DVD -> -- you have a DVD
DVDDrive True k a -> -- you know how to continue full
DVDDrive False k a -- so you can insert from empty
DEject :: (DVD -> -- once you receive a DVD
DVDDrive False k a) -> -- you know how to continue empty
DVDDrive True k a -- so you can eject when full
instance IxMonad DVDDrive where -- put these methods where they need to go
ireturn = DReturn -- so this goes somewhere else
ibind (DReturn a) k = k a
ibind (DInsert dvd j) k = DInsert dvd (ibind j k)
ibind (DEject j) k = DEject j $ \ dvd -> ibind (j dvd) k
इसके स्थान पर, हम "आदिम" कमांड को परिभाषित कर सकते हैं
dInsert :: DVD -> DVDDrive False True ()
dInsert dvd = DInsert dvd $ DReturn ()
dEject :: DVDrive True False DVD
dEject = DEject $ \ dvd -> DReturn dvd
जिसमें से अन्य लोगों के साथ इकट्ठे होते हैं ireturn
और ibind
। अब, मैं लिख सकता हूँ (उधार- do
भुगतान)
discSwap :: DVD -> DVDDrive True True DVD
discSwap dvd = do dvd' <- dEject; dInsert dvd ; ireturn dvd'
लेकिन शारीरिक रूप से असंभव नहीं है
discSwap :: DVD -> DVDDrive True True DVD
discSwap dvd = do dInsert dvd; dEject -- ouch!
वैकल्पिक रूप से, कोई व्यक्ति किसी आदिम कमांड को सीधे परिभाषित कर सकता है
data DVDCommand :: Bool -> Bool -> * -> * where
InsertC :: DVD -> DVDCommand False True ()
EjectC :: DVDCommand True False DVD
और फिर जेनेरिक टेम्प्लेट को तत्काल करें
data CommandIxMonad :: (state -> state -> * -> *) ->
state -> state -> * -> * where
CReturn :: a -> CommandIxMonad c i i a
(:?) :: c i j a -> (a -> CommandIxMonad c j k b) ->
CommandIxMonad c i k b
instance IxMonad (CommandIxMonad c) where
ireturn = CReturn
ibind (CReturn a) k = k a
ibind (c :? j) k = c :? \ a -> ibind (j a) k
वास्तव में, हमने कहा है कि आदिम क्लेसीली तीर क्या हैं (एक "डोमिनो" क्या है), फिर उनके ऊपर "गणना अनुक्रम" की एक उपयुक्त धारणा बनाई।
ध्यान दें कि प्रत्येक अनुक्रमित मोनाड के लिए m
, "कोई परिवर्तन विकर्ण नहीं" m i i
एक सनक है, लेकिन सामान्य रूप से, m i j
नहीं है। इसके अलावा, मूल्यों को अनुक्रमित नहीं किया जाता है, लेकिन संगणनों को अनुक्रमित किया जाता है, इसलिए एक अनुक्रमित मोनाड किसी अन्य श्रेणी के लिए मोनाड तत्काल का सामान्य विचार नहीं है।
अब, फिर से क्लीसली तीर के प्रकार को देखें
a -> m i j b
हम जानते हैं कि हमें i
शुरू करने के लिए राज्य में होना चाहिए , और हम भविष्यवाणी करते हैं कि कोई भी निरंतरता राज्य से शुरू होगी j
। हम इस प्रणाली के बारे में बहुत कुछ जानते हैं! यह एक जोखिम भरा ऑपरेशन नहीं है! जब हम डीवीडी को ड्राइव में डालते हैं, तो यह अंदर चला जाता है! प्रत्येक कमांड के बाद राज्य में डीवीडी ड्राइव का कोई मतलब नहीं है।
लेकिन यह सामान्य रूप से सच नहीं है, जब दुनिया के साथ बातचीत करते हैं। कभी-कभी आपको कुछ नियंत्रण छोड़ने की ज़रूरत होती है और दुनिया को वही करना चाहिए जो उसे पसंद है। उदाहरण के लिए, यदि आप एक सर्वर हैं, तो आप अपने ग्राहक को एक विकल्प प्रदान कर सकते हैं, और आपका सत्र राज्य इस बात पर निर्भर करेगा कि वे क्या चुनते हैं। सर्वर का "प्रस्ताव पसंद" ऑपरेशन परिणामी स्थिति को निर्धारित नहीं करता है, लेकिन सर्वर को वैसे भी ले जाने में सक्षम होना चाहिए। यह उपरोक्त अर्थों में एक "आदिम कमांड" नहीं है, इसलिए अनपेक्षित परिदृश्य को मॉडल करने के लिए अनुक्रमित भिक्षु इतने अच्छे उपकरण नहीं हैं।
एक बेहतर उपकरण क्या है?
type f :-> g = forall state. f state -> g state
class MonadIx (m :: (state -> *) -> (state -> *)) where
returnIx :: x :-> m x
flipBindIx :: (a :-> m b) -> (m a :-> m b) -- tidier than bindIx
डरावना बिस्कुट? वास्तव में नहीं, दो कारणों से। एक, यह, क्या एक इकाई है की तरह नहीं बल्कि अधिक लग रहा है, क्योंकि यह है एक इकाई है, लेकिन अधिक (state -> *)
के बजाय *
। दो, यदि आप क्लेस्ली तीर के प्रकार को देखते हैं,
a :-> m b = forall state. a state -> m b state
आप एक पुराने पूर्व a
संस्मरण की b
तरह एक पूर्व शर्त और पोस्टकंडिशन के साथ अभिकलन के प्रकार प्राप्त करते हैं । करी-हावर्ड पत्राचार को पार करने और हास्केल प्रकार बनने के लिए कार्यक्रम लॉजिक्स में जोर आधी सदी के भीतर लिया गया है। इस प्रकार का returnIx
कहना है "आप किसी भी पोस्टकॉन्डिशन को प्राप्त कर सकते हैं, जो कि कुछ भी करने से बस पकड़ता है", जो कि "स्किप" के लिए होरे लॉजिक नियम है। संबंधित संरचना "," के लिए होएर लॉजिक नियम है।
आइए bindIx
, सभी मात्राओं को अंदर डालते हुए , इसके प्रकार को देखें ।
bindIx :: forall i. m a i -> (forall j. a j -> m b j) -> m b i
ये forall
विपरीत ध्रुवीयता रखते हैं। हम प्रारंभिक स्थिति चुनते हैं i
, और एक संगणना जो i
पोस्टकॉन्डिशन के साथ शुरू हो सकती है a
। दुनिया किसी भी मध्यवर्ती राज्य को चुनती j
है जिसे वह पसंद करता है, लेकिन यह हमें सबूत देना चाहिए कि पोस्टकॉन्डिशन b
रखती है, और ऐसे किसी भी राज्य से हम b
पकड़ बनाने के लिए आगे बढ़ सकते हैं। तो, क्रम में, हम b
राज्य से स्थिति प्राप्त कर सकते हैं i
। "के बाद" राज्यों पर अपनी पकड़ जारी करके, हम अप्रत्याशित गणना कर सकते हैं ।
दोनों IxMonad
और MonadIx
उपयोगी हैं। क्रमशः बदलते राज्य, पूर्वानुमेय और अप्रत्याशित, के संबंध में संवादात्मक संगणना की दोनों मॉडल वैधता। जब आप इसे प्राप्त कर सकते हैं तो पूर्वनिर्धारणता मूल्यवान है, लेकिन अप्रत्याशितता कभी-कभी जीवन का एक तथ्य है। उम्मीद है, तब, यह जवाब कुछ संकेत देता है कि अनुक्रमित भिक्षु क्या हैं, दोनों की भविष्यवाणी करते हुए कि वे कब उपयोगी होना शुरू करते हैं और कब रुकते हैं।
True
/False
तर्कों को प्रकार तर्क के रूप में कैसे पारित कर सकते हैंDVDDrive
? क्या कुछ विस्तार है, या बूलियंस वास्तव में यहां टाइप हैं?