2010-04-07 11 views
9

मैंने अपने सिर को मोनाड्स के चारों ओर लपेट लिया है (कम से कम मुझे लगता है कि मेरे पास है) और अधिक विशेष रूप से राज्य मोनैड, जो कुछ लोग बुद्धिमान हैं, तो मुझे पता चला है, इसलिए मैं शायद यह प्रश्न।राज्य मोनाड, क्यों नहीं एक ट्यूपल?

वैसे भी, राज्य इकाई आम तौर पर एक एम के साथ लागू किया गया है < 'एक> की तरह इस (एफ #) कुछ के रूप में:

type State<'a, 'state> = State of ('state -> 'a * 'state) 

अब मेरे सवाल: वहाँ किसी भी कारण है कि आप एक टपल उपयोग नहीं कर सका है यहाँ? अन्य तो MonadA<'a, 'b> और MonadB<'a, 'b> के बीच संभावित अस्पष्टता जो दोनों ('a * 'b) टुपल के बराबर बन जाएंगी।

संपादित करें: स्पष्टता के लिए उदाहरण जोड़ा

type StateMonad() = 
    member m.Return a = (fun s -> a, s) 
    member m.Bind(x, f) = (fun s -> let a, s_ = x s in f a s_) 

let state = new StateMonad() 
let getState = (fun s -> s, s) 
let setState s = (fun _ ->(), s) 
let execute m s = m s |> fst 
+0

प्रश्न क्या है? एक टुपल का प्रयोग करें जहां? फ़ंक्शन का रिटर्न प्रकार एक टुपल है। – Brian

+0

कोई भी राज्य प्रकार के बजाय एक tuple का उपयोग नहीं करें और बस एक राज्य के बजाय एक समारोह वापस। – thr

उत्तर

12

राज्य इकाई अनिवार्य रूप से एक प्रकार 'state -> 'res * 'state है, जो एक गणना है कि कुछ प्रारंभिक अवस्था लेता है और परिणाम पैदा करता है (एक साथ राज्य के एक नए मूल्य के साथ) का प्रतिनिधित्व करता है के साथ काम करता है।

यदि आप पूछ रहे हैं कि इससे कोई फर्क पड़ता है कि क्या हम इस प्रकार के कुछ विशेष नाम देते हैं (उदा। State<'state, 'res>) तो जवाब यह वास्तव में कोई फर्क नहीं पड़ता। इस प्रकार के कुछ विशेष नाम देने का एकमात्र उद्देश्य यह है कि यह कोड को और अधिक पठनीय बनाता है। उदाहरण के लिए, निम्न उदाहरण के दो संभव प्रकार हस्ताक्षर को देखो:

let foo n = state { 
    let! m = getState() 
    do! setState(m + 1) 
    return sprintf "Result: %d" (n * m) } 

// Using State<'state, 'res> type: 
val foo : int -> State<int, string> 

// Using the underlying representation: 
val foo : int -> int -> int * state 

पहले प्रकार हस्ताक्षर अधिक स्पष्ट रूप से कहा गया है कि हम कुछ इकाई में समारोह लिख रहे हैं। दूसरा उदाहरण सिर्फ एक समारोह है जो दो int मान लेता है। मुझे लगता है कि पहले का मुख्य लाभ यह है कि आप आसानी से महसूस कर सकते हैं कि इस प्रकार का उपयोग अन्य monadic गणना से किया जा सकता है (state { ... } का उपयोग करके लिखा गया है)।

हालांकि, जैसा कि मैंने पहले ही उल्लेख किया है, यह तकनीकी आवश्यकता नहीं है। लोग शायद इस शैली, एक अच्छा विचार की तरह एक परिभाषित करने के लिए उपयोग करें, क्योंकि कई monads हास्केल, जहां monads प्रकार (जैसे State<'state, 'res> के रूप में) और नहीं एक गणना बिल्डर (जैसे state के रूप में) से जुड़े हैं से आते हैं तो यह लग रहा है हास्केल में हर मोनड के लिए नया प्रकार।

+0

धन्यवाद, हाँ, मुझे टुपल संस्करण का उपयोग करने का कोई इरादा नहीं है, मैं केवल आईआरसी (## fsharp @ freenode) पर चर्चा कर रहा था और हम में से कोई भी राज्य के प्रकार के लिए तकनीकी कारण नहीं देख सकता था। – thr

5

आह, हाँ, अगर सवाल यह है: मैं एक एकल टैग भेदभाव संघ प्रकार टी के एक डेटा मूल्य वहन करती है का उपयोग करना चाहिए, या मैं सिर्फ चाहिए टी का प्रयोग करें, फिर आप या तो उपयोग कर सकते हैं।

हास्केल में, आप के बाद से हास्केल do वाक्य रचना इकाई मूल्य प्रकार के आधार पर प्रकार (एक टपल प्रतिनिधित्व ज्यादा से ज्यादा एक भी इकाई का एक उदाहरण हो सकता है) infers, monads साथ एक डेटा टैग का उपयोग करने की जरूरत है। जबकि एफ # में, गणना अभिव्यक्ति मोनैड प्रकार (उदा। state { ... } या async { ... } या जो भी हो) के बारे में स्पष्ट हैं, इसलिए यह प्रतिबंध आवश्यक नहीं है, एक ही प्रतिनिधित्व प्रकार एकाधिक मोनैड के लिए उपयोग किया जा सकता है।

6

अपने उदाहरण में monadic मूल्य के प्रकार के सिर्फ एक टपल नहीं है - यह एक समारोह लौटने टपल है:

'state -> 'res * 'state 

आप कि क्या आप के प्रकार के रूप में सिर्फ 'state * 'res उपयोग कर सकते हैं पूछ रहे हैं monadic गणना, तो जवाब नहीं है।यह काम नहीं करेगा, क्योंकि रिटर्न ऑपरेशन को लागू करने (सुरक्षित रूप से) करने का कोई तरीका नहीं है, जिसके लिए निम्न प्रकार का हस्ताक्षर होना चाहिए:

// how would we get a value of type 'state in the implementation? 
val return : 'a -> 'state * 'a 
संबंधित मुद्दे