दो monads, Monad m
और Monad n
दिए गए, मैं m (n a)
n (m a)
में बदलना चाहता हूं। लेकिन ऐसा कोई सामान्य तरीका नहीं है क्योंकि (>>=)
और return
दोनों केवल एक मोनैड प्रकार से संबंधित हैं, और हालांकि (>>=)
एक मोनैड से सामग्री निकालने की अनुमति देता है, तो आपको उन्हें उसी मोनैड प्रकार पर पैक करना होगा ताकि यह परिणाम मूल्य हो।monads repacking - कोई सामान्य तरीका?
हालांकि, अगर हम m
को एक निश्चित प्रकार पर सेट करते हैं, तो नौकरी आसान हो जाती है। एक उदाहरण के रूप Maybe
लें:
reorder :: (Monad n) => Maybe (n a) -> n (Maybe a)
reorder Nothing = return Nothing
reorder (Just x) = do
x' <- x
return $ Just x'
या एक सूची: देखने के लिए
reorder :: (Monad n) => [n a] -> n [a]
reorder [] = return []
reorder (x:xs) = do
x' <- x
xs' <- reorder xs
return (x':xs')
कठिन नहीं, हम यहाँ एक पैटर्न मिल गया है। और अधिक स्पष्ट होने के लिए, एक Applicative
तरीके से लिखते हैं, और यह प्रत्येक तत्व के लिए डेटा निर्माता को लागू करने से अधिक नहीं है:
reorder (Just x) = Just <$> x
reorder (x:xs) = (:) <$> x <*> (reorder xs)
मेरे सवाल यह है: एक haskell typeclass पहले से ही इस तरह के आपरेशनों का वर्णन करने के लिए मौजूद है, या मैं क्या करता है खुद पहिया का आविष्कार करना है?
मुझे जीएचसी दस्तावेज में एक संक्षिप्त खोज थी, और इस विषय के लिए कुछ भी उपयोगी नहीं मिला।
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
GHC भी समर्थन स्वचालित रूप से पाने उदाहरण के लिए प्रदान करता है::
यह, ज़ाहिर है, केवल तभी काम करता है जब आपका बाहरी प्रकार का कन्स्ट्रक्टर 'ट्रैवर्सबल' (सभी 'मोनाद नहीं हैं)। बोनस यह है कि आंतरिक व्यक्ति को केवल 'आवेदक' होना चाहिए। –