आप कंक्रीट मोनैड स्टैक्स के बजाय टाइपक्लास का उपयोग करके अपने कार्यों को मोनाड-अज्ञेयवादी बना सकते हैं।
bangMe :: State String()
bangMe = do
str <- get
put $ str ++ "!"
-- or just modify (++"!")
बेशक
, आपको लगता है कि यह भी एक ट्रांसफॉर्मर के रूप में काम करता है, इसलिए एक लिख सकते हैं::
मान लीजिए कि आप उदाहरण के लिए इस समारोह है, कि चलो
bangMe :: Monad m => StateT String m()
हालांकि, यदि आपके पास एक ऐसा फ़ंक्शन है जो एक अलग स्टैक का उपयोग करता है, तो मान लें कि ReaderT [String] (StateT String IO)()
या जो भी हो, आपको ड्रेडेड lift
फ़ंक्शन का उपयोग करना होगा! तो यह कैसे टाला जाता है?
चाल फ़ंक्शन हस्ताक्षर को और अधिक सामान्य बनाने के लिए है, ताकि यह कह सके कि State
मोनड मोनैड स्टैक में कहीं भी दिखाई दे सकता है। यह इस तरह से किया जाता है:
bangMe :: MonadState String m => m()
यह बलों m
एक इकाई है कि राज्य (लगभग) का समर्थन करता है इकाई ढेर में कहीं भी हो सकता है, और समारोह इस प्रकार किसी भी तरह के ढेर के लिए बिना किसी मेहनत के काम करेंगे।
हालांकि, एक समस्या है; चूंकि IO
mtl
का हिस्सा नहीं है, इसमें ट्रांसफार्मर नहीं है (उदा। IOT
) न ही प्रति डिफ़ॉल्ट प्रकार की एक आसान श्रेणी। तो जब आप आईओ कार्यों को मनमाने ढंग से उठाना चाहते हैं तो आपको क्या करना चाहिए?
बचाव के लिए MonadIO
आता है!यह MonadState
, MonadReader
आदि के लगभग समान रूप से व्यवहार करता है, केवल अंतर यह है कि इसमें थोड़ा अलग उठाने की व्यवस्था है। यह इस प्रकार काम करता है: आप IO
एक्शन ले सकते हैं, और इसे liftIO
का उपयोग एक मोनड अज्ञेय संस्करण में बदलने के लिए करें। तो:
action :: IO()
liftIO action :: MonadIO m => m()
monadic कार्रवाई आप इस तरह से उपयोग करना चाहते हैं के सभी बदलने करके, आप किसी कठिन उठाने के बिना जितना आप चाहते हैं के रूप में monads बटना कर सकते हैं।
ओह मुझे लगता है कि मैं बेवकूफ महसूस करता हूं, आपने उल्लेख किया है कि आपके पिछले उत्तरों में से एक में, मैं उस समय इसे समझ नहीं पाया। अब, मैं धन्यवाद! – aelguindy