2009-09-25 17 views
21

मैं this हास्केल पर ट्यूटोरियल पढ़ रहा हूं। वे निम्नलिखित के रूप में समारोह रचना को परिभाषित:हास्केल फ़ंक्शन संरचना

(.)      :: (b->c) -> (a->b) -> (a->c) 
f . g     = \ x -> f (g x) 

कोई उदाहरण नहीं प्रदान किया गया, मेरा मानना ​​है कि जो मुझे यहाँ क्या परिभाषित किया जा रहा है के रूप में प्रबुद्ध जाएगा।

क्या कोई फ़ंक्शन संरचना का उपयोग करने के बारे में एक सरल उदाहरण (स्पष्टीकरण के साथ) प्रदान कर सकता है?

उत्तर

38

फ़ंक्शन संरचना एक ही फ़ंक्शन में दो कार्यों को एक साथ "रचना" करने का एक तरीका है। यहाँ एक उदाहरण है:

आप इन कार्यों कहते हैं:

even :: Int -> Bool 
not :: Bool -> Bool 

और आप ऊपर दो का उपयोग कर अपनी खुद की myOdd :: Int -> Bool समारोह को परिभाषित करना चाहते।

myOdd :: Int -> Bool 
myOdd x = not (even x) 

लेकिन यह अधिक संक्षेप समारोह रचना का उपयोग किया जा सकता है::

myOdd :: Int -> Bool 
myOdd = not . even 

myOdd कार्यों बिल्कुल वैसा ही व्यवहार करते हैं, लेकिन दूसरे

यह करने के लिए स्पष्ट तरीका निम्न है एक "गोंद-आईएनजी" द्वारा दो कार्यों को एक साथ बनाया गया है।

एक परिदृश्य जहां यह विशेष रूप से उपयोगी है, एक स्पष्ट लैम्ब्डा की आवश्यकता को दूर करना है। उदा: थोड़ा छोटा होता है, त्रुटियों के लिए कम कमरे

map (not . even) [1..9] 

:

map (\x -> not (even x)) [1..9] 

फिर से लिखा जा सकता है।

+0

के लिए +1 आपको परिभाषा में इनपुट पैरामीटर दिखाने की आवश्यकता नहीं है? उदाहरण के लिए। आप कैसे 'myOdd x = नहीं लिखते हैं। यहां तक ​​कि एक्स'? – unclerojelio

+2

@unclerojelio इसे पॉइंट-फ्री शैली कहा जाता है। किसी दिए गए तर्क के परिणाम के संदर्भ में 'myOdd' को परिभाषित करने के बजाय ("दिया गया' x',' myOdd' '(नहीं।) X' "के समान मान देता है), यह वास्तव में इसके संदर्भ में परिभाषित किया गया है है ("myOdd' वह फ़ंक्शन है जिसके परिणामस्वरूप ''''' के साथ बना नहीं है")। – chepner

13

रचना f और g की है कि पहले अपने तर्क है, तो fg द्वारा दिए गए मान के लिए लागू होता है g एक समारोह है। इसके बाद यह f का रिटर्न वैल्यू देता है।

यह पहचान शिक्षाप्रद हो सकता है:

int f(int x); 
int g(int x); 
int theComposition(int x) { return f(g(x)); } 
+0

समकक्ष – outis

4
HaskellWiki page on function composition:

desort = (reverse . sort) 

से

अब desort है:

f (g x) = (f . g) x

आप एक जावा/सी पृष्ठभूमि है, इस उदाहरण पर विचार एक फ़ंक्शन जो रिवर्स में एक सूची टाइप करता है। असल में, desortsort में इसके तर्कों को खिलाता है, और फिर sort से reverse में वापसी मान फ़ीड करता है, जो एक रिटर्न है। तो यह इसे टाइप करता है, और फिर यह क्रमबद्ध सूची को उलट देता है।

7

यह उदाहरण काल्पनिक है, लेकिन लगता है कि हम

sqr x = x * x 
inc x = x + 1 

है और हम एक समारोह है कि गणना करता है x^2 + 1 लिखना चाहते हैं। हम

xSquaredPlusOne = inc . sqr 

लिख सकते हैं (जिसका अर्थ है

xSquaredPlusOne x = (inc . sqr) x 

जो

xSquaredPlusOne x = inc(sqr x) 

का मतलब है के बाद से च = इंक और जी = sqr)।

26

मज़ा पक्ष नोट। फंक्शन संरचना तर्क में एक syllogism के बराबर है:

सभी पुरुष प्राणघातक हैं। सॉक्रेटीस एक आदमी है। इसलिए, सॉक्रेटीस प्राणघातक है।

(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal) 

इसलिए ...

(b -> c) -> (a -> b) -> (a -> c) 

... जो . समारोह के प्रकार है:

एक न्याय एक में दो सामग्री निहितार्थ तैयार करता।

3

फ़ंक्शन संरचना दो या दो से अधिक कार्यों को एक साथ करने का एक तरीका है। इसे अक्सर खोल पाइपिंग की तुलना में किया जाता है। उदाहरण के लिए, एक यूनिक्स शैली खोल में, आप की तरह

cat foo.txt | sort -n | less 

यह cat चलाता है, sort को इसके उत्पादन फ़ीड, और less है कि से उत्पादन फ़ीड कुछ लिख सकते हैं।

कड़ाई से, यह हास्केल $ ऑपरेटर की तरह है। आप

sum $ sort $ filter (> 0) $ my_list 

पर ध्यान दें कि खोल उदाहरण के विपरीत, यह दाएं से बाएं पढ़ता है। तो हम इनपुट के रूप में my_list के साथ शुरू करते हैं, फिर हम filter चलाते हैं, फिर हम sort इसे चलाते हैं, और फिर हम sum की गणना करते हैं।

फ़ंक्शन संरचना ऑपरेटर, ., कुछ ऐसा ही करता है। उपरोक्त उदाहरण संख्या उत्पन्न करता है;

sum . sort . filter (> 0) 

सूचना है कि हम वास्तव में इस में एक सूची फ़ीड नहीं किया: नीचे दिए गए उदाहरण एक समारोह पैदा करता है। इसके बजाए, हमने अभी एक नया फ़ंक्शन बनाया है, और हम उस फ़ंक्शन में कई अलग-अलग सूचियां खिला सकते हैं।उदाहरण के लिए, आप इस समारोह का नाम हो सकता है:

my_function = sum . sort . filter (> 0) 

या आप एक और कार्य करने के लिए एक तर्क के रूप में यह पारित हो सकता है:

map (sum . sort . filter (> 0)) my_lists 

आप मूल रूप से इसे कहीं भी उपयोग कर सकते हैं कि आप समारोह के किसी भी अन्य प्रकार का उपयोग कर सकते हैं । यह कहने का एक तेज़ और पठनीय तरीका है "मैं इन कार्यों को एक साथ जोड़ना चाहता हूं"।

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