2012-04-20 5 views
27

मैं आवेदक फ़ैक्टर के बारे में पढ़ रहा हूं, विशेष रूप से मैकब्राइड और पैटरसन द्वारा कार्यात्मक पर्ल में। लेकिन मैं कुछ अभ्यास करके मेरी समझ को मजबूत करना चाहता हूं। मैं प्रोग्रामिंग अभ्यास पसंद करूंगा लेकिन सबूत अभ्यास भी ठीक है। कौन से अभ्यास मुझे आवेदक के साथ प्रभावी ढंग से प्रोग्राम सीखने में मदद करेंगे?आवेदक functors के लिए प्रोग्रामिंग अभ्यास कहां मिलना है?

व्यक्तिगत अभ्यास ठीक है जैसे कहीं और सूचीबद्ध अभ्यासों के पॉइंटर्स हैं।

+3

मैं अभ्यास का सुझाव नहीं दे सकता, लेकिन आप उन आवेदक फंक्शंस देख सकते हैं जो मोनैड नहीं हैं (एक महत्वपूर्ण सवाल यह है कि "एक मोनैड से कम शक्तिशाली होने पर आवेदक मज़ेदार क्यों डिजाइन करें?")। बहु त्रुटि आवेदक (पैटरसन और मैकब्राइड में) एक है, डोएत्से स्विएरस्ट्रा के पार्सर्स भी हैं, एंडी गिल और केविन मैटलज के चॉकबोर्ड में एक एनीमेशन एक _ एक्टिव_ प्लस मुझे लगता है कि एंडी गिल और सहयोगी 'कान्सास लावा एक आवेदक मज़ेदार पर आधारित है। –

उत्तर

20

कुछ प्रश्नों को उत्तर के रूप में पोस्ट करने में मनोरंजक लगता है। सुडोकू के आधार पर Applicative और Traversable के बीच इंटरप्ले पर यह एक मजेदार है।

(1) विचार करें

data Triple a = Tr a a a 

का निर्माण

instance Applicative Triple 
instance Traversable Triple 

ताकि Applicative उदाहरण "vectorization" करता है और Traversable उदाहरण बाएँ से सही काम करता है। उपयुक्त Functor उदाहरण बनाने के लिए मत भूलना: जांचें कि आप इसे Applicative या Traversable उदाहरण से निकाल सकते हैं। आपको

newtype I x = I {unI :: x} 

बाद वाले के लिए उपयोगी हो सकता है।

(2) पर विचार करें

newtype (:.) f g x = Comp {comp :: f (g x)} 

दिखाओ कि

instance (Applicative f, Applicative g) => Applicative (f :. g) 
instance (Traversable f, Traversable g) => Traversable (f :. g) 

अब परिभाषित

type Zone = Triple :. Triple 

मान लीजिए हम क्षैतिज क्षेत्रों

की एक ऊर्ध्वाधर क्षेत्र के रूप में एक Board प्रतिनिधित्व करते हैं

traverse की कार्यक्षमता का उपयोग करके वर्टिकल जोन के क्षैतिज क्षेत्र के रूप में और वर्गों के वर्ग के रूप में इसे पुनर्व्यवस्थित करने के तरीके को दिखाएं।

(3) पर विचार करें

newtype Parse x = Parser {parse :: String -> [(x, String)]} deriving Monoid 

या कुछ अन्य उपयुक्त निर्माण (यह देखते हुए कि के लिए पुस्तकालय Monoid व्यवहार | शायद | अनुचित है)।निर्माण

instance Applicative Parse 
instance Alternative Parse -- just follow the `Monoid` 

और

ch :: (Char -> Bool) -> Parse Char 

जो खपत और एक चरित्र बचाता है अगर यह किसी दिए गए विधेय द्वारा स्वीकार किया जाता लागू।

(4) एक पार्सर जो खाली स्थान के लिए किसी भी मात्रा की खपत, एक भी अंक की लागू (0 कारतूस का प्रतिनिधित्व करता है)

square :: Parse Int 

उपयोग pure और traverse के निर्माण के लिए

board :: Parse (Board Int) 

(5) निरंतर मज़दूरों पर विचार करें

newtype K a x = K {unK :: a} 

और constru सीटी

instance Monoid a => Applicative (K a) 

तो traverse का उपयोग लागू करने के लिए

crush :: (Traversable f, Monoid b) => (a -> b) -> f a -> b 

Bool के लिए newtype रैपर का निर्माण इसके संयोजक और वियोगी monoid संरचनाओं व्यक्त। any और all के संस्करणों को लागू करने के लिए crush का उपयोग करें जो Traversable फ़ैक्टर के लिए काम करता है।

(6) को लागू करें

duplicates :: (Traversable f, Eq a) => f a -> [a] 

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

(7) को लागू करें

complete :: Board Int -> Bool 
ok :: Board Int -> Bool 

जो जाँच एक बोर्ड है अगर (1) पूर्ण केवल किसी भी पंक्ति, कॉलम या बॉक्स में डुप्लीकेट से रहित [1..9] और (2) में अंकों का।

+0

ग्रेट व्यायाम! – luqui

5

Typeclassopedia देखें। यह जमीन से एक अच्छी व्याख्या और रास्ते में कुछ अभ्यास के साथ आता है।

4

उदाहरण के लिए: Applicative Functors

+0

यह लिंक मृत लगता है, लेकिन [यह इंटरनेट आर्काइव वेबैक मशीन पर पृष्ठ है] (https://web.archive.org/web/*/http://www.cis.upenn.edu/~cis194/lectures/ *): [फ़ंक्शंस] (https://web.archive.org/web/20130803145920/http://www.cis.upenn.edu/~cis194/lectures/09-functors.html); [आवेदक फ़ैक्टर] [https://web.archive.org/web/20130803134207/http://www.cis.upenn.edu/~cis194/lectures/10-applicative.html) –

12

एक शानदार तरीका अभ्यास करने के लिए नहीं बल्कि एक monadic शैली की तुलना में एक अनुप्रयोगी में Parsec उपयोग करने के लिए है। अधिकांश पार्सर्स पूरी तरह से आवेदक होते हैं, इसलिए आपको do नोटेशन का उपयोग करने की आवश्यकता नहीं है।

ईजी। अभिव्यक्तियों के लिए:

import qualified Text.Parsec as P 
import qualified Text.Parsec.Token as P 
import Control.Applicative 

data Expr = Number Int | Plus Expr Expr 

lex = P.makeTokenParser ... -- language config 

expr = number <|> plus 
    where 
    number = Number <$> P.integer lex 
    plus = Plus <$> number <* P.symbol lex "+" <*> expr 
+0

मैं उत्सुक हूं- -क्या आप कुछ आम या कम से कम उचित उदाहरण दे सकते हैं जिन्हें आप * आवेदक के साथ पार्स नहीं कर सकते लेकिन मोनड के साथ कर सकते हैं? –

+7

@ टिखोनजेल्विस, * औपचारिक रूप से * वे कम से कम एक सीमित वर्णमाला पर शक्ति में बराबर हैं, लेकिन एक रोगजनक तरीके से (वे दोनों अनंत व्याकरण का समर्थन करते हैं)। लेकिन एक अच्छा उदाहरण है जहां आप (उचित रूप से) एक मोनड की आवश्यकता होगी, यदि आपके पास ऐसी भाषा थी जो नई व्याकरणिक संरचनाओं को परिभाषित कर सकती है जिसे बाद में पार्स में ध्यान में रखा जाना चाहिए।'आवेदक 'अपनी * संरचना *,' मोनाड' कर सकते हैं के आधार पर * * संरचना * को बदल नहीं सकता है। – luqui

+0

+1 जब मैंने शीर्षक देखा, तो मैंने तुरंत पारसेक के बारे में सोचा। दिलचस्प, नॉनट्रिविअल, अभी तक सरल समस्याओं को हल करने का अभ्यास करने का यह एक शानदार तरीका है। –

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