2015-09-15 4 views
6

निर्धारित करता है, तो एक स्ट्रिंग यहाँ विलोमपदव्यवहार >> = (==)

pal1 = (==) <$> reverse <*> id 

के माध्यम से एक pointfree अनुप्रयोगी ढंग से लागू किया जा सकता है और के लिए एक समारोह एक monadic संस्करण

reverse >>= (==) 
है

मोडैडिक संस्करण आईडी के लिए कोई स्पष्ट कॉल के साथ कैसे काम करता है? मैंने पॉइंटफुल का उपयोग करके सूचक प्रतिनिधित्व को देखने का प्रयास किया और उसी कार्य को वापस प्राप्त किया।

+2

https://stackoverflow.com/questions/14430397/about-the-function-monad – Ryan

उत्तर

8

यह इस तथ्य का उपयोग करता है कि x -> y को "रीडर मोनड" के रूप में माना जा सकता है। अगर हम

type Reader r x = r -> x 

तो हमारे पास Monad (Reader r) का उदाहरण है। तो हम देख सकते हैं कि

reverse :: [x] -> [x] 

वास्तव में

reverse :: Reader [x] [x] 

इसी तरह है,

(==) :: [x] -> [x] -> Bool 

(==) :: [x] -> Reader [x] Bool 

के रूप में लिखा जा सकता है तो फिर (>>=) दोनों एक साथ जुड़ जाता है।

तो ... हम reverse से शुरू करते हैं, जो Reader क्रिया है जो एक सूची पढ़ता है और एक सूची देता है। हम का उपयोग == को पास करने के लिए करते हैं, जो एक ऐसा कार्य है जो एक सूची लेता है, और Reader [x] Bool देता है।

संक्षेप में, इनपुट सूची Reader की क्रिया द्वारा डुप्लिकेट की गई है, जो मूल रूप से इनपुट लेती है और इसे श्रृंखला में प्रत्येक फ़ंक्शन पर पास करती है। (यही कारण है कि पाठक इकाई है।)

मुझे आशा है कि समझ में किसी तरह का बना दिया ... यह मुझे कुछ समय लिया यह पता लगाने की!

instance Monad ((->) r) where 
    return = const 
    f >>= k = \ r -> k (f r) r 

और फिर बस अपने monadic कोड भरें::

+1

ओह, एक 'रीडर' प्रकार समानार्थी बनाना जो वाकई स्पष्टीकरण को स्पष्ट करता है! बढ़िया विचार है। मैं अगली बार इसे चोरी करने जा रहा हूं, मुझे '((->) आर) के लिए मोनैड इंस्टेंस के बारे में बात करने की ज़रूरत है क्योंकि यह वाक्यविन्यास बहुत भ्रमित है: पी। –

5

के ((->) r) के लिए इकाई कहने पर एक नजर है

reverse >>= (==) = \r -> (==) (reverse r) r 

जो हम एक अधिक परिचित रास्ते में लिख सकते हैं:

\r -> reverse r == r 
4

अन्य उत्तरों में जोड़ने के लिए, यहां एक और पीओवी है। के fmap और join के माध्यम से बाँध की एक परिभाषा लेते हैं:

m >>= act = join (fmap act m) 

अभिव्यक्ति (==) <$> reverse टाइप Eq a => [a] -> [a] -> Bool है और fmap (==) reverse के बराबर है।अब, हम इसे join :: m (m a) -> m a पर पास करते हैं और (->) r मोनैड उदाहरण के लिए टाइप ([a] -> [a] -> Bool) -> ([a] -> Bool) होगा। यही है, शामिल है वास्तव में <*> id भाग है।

1

मुझे लगता है यह समझने के लिए सबसे आसान तरीका है प्रकार को देखकर है:

(>>=) :: Monad m => m a -> (a -> m b) -> m b 

((->) r) उदाहरण के लिए विशेष:

(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b 

आप नहीं दिया जाता है एक a। एक उत्पादित करने का एकमात्र तरीका यह है कि आपको r पर दिए गए पहले फंक्शन r -> a को लागू करना है। b का उत्पादन करने का एकमात्र तरीका r और a पर दूसरा फ़ंक्शन लागू करना है जिसे आपने अभी बनाया है। इसका मतलब यह है इस समारोह * के लिए ही संभव परिभाषा है:

f >>= g = \a -> g (f a) a 

में, हम पाते हैं हमारे तर्कों Plugging:

reverse >>= (==) 

-- definition of (>>=) 
= \a -> (==) (reverse a) a 

-- prefix to infix 
= \a -> reverse a == a 

Parametricity बहुरूपी कार्यों के बारे में तर्क के लिए एक शक्तिशाली उपकरण है।


* से नीचे

1

अन्य अन्य उत्तर पुष्टि करते हैं कि दो ही व्यवहार करते हैं, लेकिन यह नहीं बताते कि जहां id वास्तव में चला गया। इस जवाब में, मैं ऐसा करने का प्रयास करूंगा। पंचलाइन यह है कि, रीडर के लिए, हमारे पास एक उत्सुक id है- समीकरण को हटा रहा है: id >>= return . f = f। (इस समीकरण का एक और सुंदर रूप यह है कि (id >>=) = (>>= id); साथ में मोनैड कानूनों के साथ सुंदर रूप आसानी से उपयोग करने योग्य रूप का तात्पर्य है।) स्पष्टीकरण को थोड़ा सरल बनाने के लिए, आवेदक रूप से मोनाडिक रूप में परिवर्तित करने की कोशिश करने के बजाय, मैं करूँगा बस इसे ले प्रदान करने के लिए है कि आपको लगता है कि निम्न समीकरण:

(==) <$> reverse <*> id 
= { too annoying to do carefully } 
reverse >>= \xs -> id >>= \ys -> return ((==) xs ys) 

तो हम उस अंतिम पंक्ति से शुरू कर देंगे, और reverse >>= (==) में खत्म। रास्ते में, यह ध्यान रखना महत्वपूर्ण होगा कि id(.) की पहचान है - जो रीडर मोनैड के लिए fmap होने के कारण होता है। यहां हम जाते हैं:

reverse >>= \xs -> id >>= \ys -> return ((==) xs ys) 
= { monad law } 
reverse >>= \xs -> fmap ((==) xs) id 
= { definition of fmap for Reader } 
reverse >>= \xs -> (.) ((==) xs) id 
= { id is the identity of fmap } 
reverse >>= \xs -> (==) xs 
= { eta reduction } 
reverse >>= (==) 

तो id >>= return . f = f का अर्थ क्या है? खैर, कार्यों को "अनुक्रमित मान" के रूप में देखते हुए, हम id को उसके सूचकांक के बराबर मान के रूप में समझ सकते हैं; और return वह मान होने के नाते जो हर जगह समान है। तो id >>= return . f कहता है "इंडेक्स x पर देखें; फिर, (अभी भी इंडेक्स x पर), उस मान को वापस करें जो इसकी अनुक्रमणिका को अनदेखा करता है और उसके पास f x मान है"। ऐसा ही होता है कि जिस इंडेक्स को हम अनदेखा करते हैं और जिस मूल्य को हम f से मेल खाते हैं - इसलिए हम सभी संकेतों को भी छोड़ सकते हैं और बस "इंडेक्स x पर देखें और f पर लागू करें"। यह समीकरण का अर्थ है।

संबंधित मुद्दे