यह एक नकारात्मक स्थिति में सामान्य रूप से नहीं किया जा सकता IO
प्रकार के कारण MonadIO
से अधिक सभी उदाहरणों। वहाँ कि विशिष्ट उदाहरण (monad-control,) के लिए ऐसा करते हैं hackage पर कुछ पुस्तकालयों रहे हैं, लेकिन क्या वे अर्थ की दृष्टि से ध्वनि कर रहे हैं पर कुछ बहस कैसे वे अपवाद को संभालने के लिए संबंध है और इसी तरह की अजीब IO
y चीजों के साथ विशेष रूप से, वहाँ हो गया है।
संपादित करें: कुछ लोगों को सकारात्मक/नकारात्मक स्थिति भेद करने में रुचि रखते हैं। असल में, कहने के लिए बहुत कुछ नहीं है (और आपने शायद इसे पहले ही सुना है, लेकिन एक अलग नाम से)। शब्दावली उपप्रकार की दुनिया से आता है।
subtyping पीछे अंतर्ज्ञान है कि "a
b
की एक उप-प्रकार (मैं a <= b
लिखेंगे जो) एक a
कहीं भी इस्तेमाल किया जा सकता है जब एक b
बजाय उम्मीद थी कि" है। उप-निर्धारण का निर्णय कई मामलों में सरल है; उत्पादों, (a1, a2) <= (b1, b2)
जब भी a1 <= b1
और a2 <= b2
, उदाहरण के लिए के लिए एक बहुत ही सरल नियम है। लेकिन कुछ मुश्किल मामले हैं; उदाहरण के लिए, हमें कब निर्णय लेना चाहिए कि a1 -> a2 <= b1 -> b2
?
ठीक है, हमारे पास f :: a1 -> a2
फ़ंक्शन है और एक संदर्भ b1 -> b2
प्रकार के फ़ंक्शन की अपेक्षा करता है। तो संदर्भ इसलिए हम चाहते हैं कि a2 <= b2
की आवश्यकता होती है चाहिए f
की वापसी मान का उपयोग करने के रूप में अगर यह एक b2
थे जा रहा है,। मुश्किल बात यह है कि संदर्भ एक b1
साथ f
की आपूर्ति किया जा रहा है, भले ही f
इसका इस्तेमाल करने के रूप में अगर यह एक a1
थे जा रहा है है। इसलिए, हमें b1 <= a1
की आवश्यकता होनी चाहिए - जो आपको लगता है कि पीछे से दिखता है! हम कहते हैं कि a2
और b2
"covariant" कर रहे हैं, या एक "सकारात्मक स्थिति" में पाए जाते हैं, और a1
और b1
"contravariant" कर रहे हैं, या एक "नकारात्मक स्थिति" में होते हैं।
(त्वरित तरफ? क्यों "सकारात्मक" और "नकारात्मक" यह गुणन से प्रेरित है इन दो प्रकार पर विचार करें:।
f1 :: ((a1 -> b1) -> c1) -> (d1 -> e1)
f2 :: ((a2 -> b2) -> c2) -> (d2 -> e2)
जब f1
रों प्रकार के प्रकार f2
की एक उप-प्रकार हो 'चाहिए मैं? इन तथ्यों को राज्य (व्यायाम: इस जाँच से ऊपर नियम का उपयोग कर):
- हम
e1 <= e2
होना चाहिए
- हम
d2 <= d1
होना चाहिए +०१२३५१६४१०६।।
- हम
c2 <= c1
होना चाहिए।
- हम
b1 <= b2
होना चाहिए।
- हम
a2 <= a1
होना चाहिए।
e1
d1 -> e1
में एक सकारात्मक स्थिति है, जो f1
के प्रकार में एक सकारात्मक स्थिति में बारी में है में है; इसके अलावा, e1
कुल मिलाकर f1
के प्रकार में सकारात्मक स्थिति में है (क्योंकि यह उपरोक्त तथ्य के अनुसार है)। पूरे शब्द में इसकी स्थिति प्रत्येक subterm में अपनी स्थिति का उत्पाद है: सकारात्मक * सकारात्मक = सकारात्मक। इसी तरह, d1
d1 -> e1
में एक नकारात्मक स्थिति में है, जो पूरे प्रकार में एक सकारात्मक स्थिति में है। ऋणात्मक * सकारात्मक = नकारात्मक, और d
चर वास्तव में contravariant हैं। b1
a1 -> b1
में सकारात्मक स्थिति में है, जो (a1 -> b1) -> c1
में नकारात्मक स्थिति में है, जो पूरे प्रकार की नकारात्मक स्थिति में है। सकारात्मक * नकारात्मक * नकारात्मक = सकारात्मक, और यह covariant है। आप अब विचार प्राप्त)
, के MonadIO
वर्ग पर एक नज़र डालें:।
class Monad m => MonadIO m where
liftIO :: IO a -> m a
हम subtyping की एक स्पष्ट घोषणा के रूप में यह देख सकते हैं: हम IO a
एक उप-प्रकार हो बनाने के लिए एक तरह से दे रहे हैं कुछ ठोस m
के लिए m a
का। तुरंत हम जानते हैं कि हम सकारात्मक स्थिति में IO
रचनाकारों के साथ कोई भी मूल्य ले सकते हैं और उन्हें m
में बदल सकते हैं। लेकिन यह सब कुछ है: हमारे पास नकारात्मक IO
रचनाकारों को m
में बदलने का कोई तरीका नहीं है - इसके लिए हमें एक और अधिक रोचक कक्षा की आवश्यकता है।
गह! सभी हास्केल इतने मेहनत क्यों कर रहे हैं? यहां कोई आसान बिंदु नहीं :-( – drozzy
@ डोज़ज़ी: यह टैग वास्तव में [प्रति जवाब उच्चतम औसत संख्या अपवॉट्स में से एक है] (http://data.stackexchange.com/stackoverflow/query/61353/tags-with-highest-Average --------टैग-कम-से-कम-1000-प्रश्नों के साथ), इसलिए जब वे हमेशा आसान नहीं होते हैं, तो लोगों को उनके प्रयासों के लिए पुरस्कृत किया जाता है। – hammar