2014-11-06 9 views
11

मुझे लगता है कि मैं यहां पूरी तरह से कुछ स्पष्ट दिख रहा हूं लेकिन बाइनरी फ़ंक्शन और एक यूनरी फ़ंक्शन लिखने के लिए पॉइंट-फ्री नोटेशन का उपयोग करने के लिए सही तरीका (यदि कोई है) क्या है? उदाहरण के लिए, निम्न कोड को संकलित करता है:एक यूनरी फ़ंक्शन के साथ बाइनरी फ़ंक्शन कैसे लिखें?

sortedAppend :: (Ord a) -> [a] -> [a] -> [a] 
sortedAppend xs ys = sort $ xs ++ ys 

लेकिन निम्नलिखित कोड संकलन नहीं करता है:

sortedAppend :: (Ord a) -> [a] -> [a] -> [a] 
sortedAppend = sort . (++) 

हम sort साथ (++) रचना करने में सक्षम हैं (क्रम में ऊपर दिखाया गया है)? यदि हां, तो कैसे?

उत्तर

17

मुझे नहीं लगता कि यह है कि इन समाधान (मेरा या अन्य) के किसी भी है कि बहुत है, लेकिन मैं पसंद करते हैं ....

let sortedAppend = (sort .) . (++) 

कारण मैं इस पसंद करते हैं, क्योंकि यह मेरे लिए आसान है के बारे में सोचना .... आप कोष्ठक उपेक्षा हैं, तो आप मूल रूप से प्रत्येक पैरामीटर

f . g --one parameter 
f . . g --two params 
f . . . g --three params 

जो समझ में आता है के लिए एक अतिरिक्त (।) जोड़ने के लिए, के बाद से g x N-1 जानकारी के साथ एक फ़ंक्शन जरूरत है ...

.... लेकिन उन की जरूरत कोष्ठक यह इतना बदसूरत बनाने ....

((f .) .) . g 
+0

+1 - अच्छा एक - मुझे यह पसंद है – Carsten

+0

@ CarstenKönig- धन्यवाद! – jamshidh

+2

[एसईसी] (http://conal.net/blog/posts/semantic-editor-combinators) परिप्रेक्ष्य: 'परिणाम = (।)', फिर 'परिणाम fg', '(result.result) fg',' (result.result.result) fg' – luqui

12

आप इस्तेमाल कर सकते हैं "उल्लू-ऑपरेटर" (कभी कभी breast.operator भी मुझे लगता है कि):

Prelude> :t (.).(.) 
(.).(.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c 

लेकिन: मुझे नहीं लगता कि आप करना चाहिए - क्या आप ने लिखा बहुत पठनीय है - इस का उपयोग करते हुए:

sortedAppend = ((.).(.)) sort (++) 

IMO

पी एस नहीं है: हाँ तुम कर सकते हो

(.:.) = (.).(.) 
sortedAppend = sort .:. (++) 

लेकिन अभी भी .... नहीं पच

पी पी एस: मैं बस पता चला कि इस ऑपरेटर एक पैकेज बुलाया में (.:) के रूप में परिभाषित किया गया है pointless-fun ^^

+5

एक अन्य संभावना: 'sortedAppend XS = तरह। (xs ++) ' –

+3

' (।)। (।) 'का एक सामान्यीकृत रूप 'fmap fmap fmap' है।ध्यान रखें कि इसे '' 'fmap' fmap' fmap''' में बदल दिया जा सकता है, जो 'fmap के बराबर है। fmap', लेकिन मुझे सबसे पहले संस्करण पसंद है। यह आपको '(+1) जैसा कुछ करने देगा।: [बस 1, कुछ भी नहीं, बस 2] 'और' [बस 2, कुछ भी नहीं, बस 3] ', या कुछ अनुक्रम $ लंबाई की तरह मिलता है।: 3 getLine दोहराएं '('fmap लंबाई $ replicateM 3 getLine' के रूप में बेहतर हो सकता है), लेकिन ऑपरेटर के लिए अन्य उपयोग हैं। अनिवार्य रूप से यह सब एक फंक्शन 2 'फंक्टर' परत गहरा नक्शा है। – bheklilr

+1

@bheklilr I * love * this - लेकिन इसे पुन: पेश करने के लिए मुझे ट्रिपल-फ्लिप को याद रखना होगा या इसे फिर से शुरू करना होगा - कुछ * अजीब * कारणों से मैं बिना किसी समस्या के '(।)। (।) को याद कर सकता हूं;) – Carsten

8

मुझे नहीं लगता कि मैं व्यक्तिगत रूप से चाहते कि जैसी चीजों के लिए निर्भरता जोड़ने की सलाह देते हैं, लेकिन पैकेज composition में Data.Composition में भी

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d 

है।

9

बस पूर्णता के लिए के लिए चलो वास्तव में अपने उदाहरण लेते हैं और धीरे-धीरे यह मुफ़्त संकेत करते हैं।

सबसे पहले, (f . g) x = f (g x) याद रखें। फिर ईटा-कमी (\x -> f x) ≡ f है। अंतिम उपयोगी बात operator section है। इन नियमों का उपयोग हम इस तरह जा सकते हैं:

sortedAppend xs ys = sort $ xs ++ ys  -- original function 
sortedAppend xs ys = sort (xs ++ ys)  -- remove $ 
sortedAppend xs ys = sort ((++) xs ys)  -- prefix application of ++ 
sortedAppend xs ys = (sort . ((++) xs)) ys -- definition of composition 
sortedAppend xs = sort . (++) xs   -- eta reduction 
sortedAppend xs = (sort .) ((++) xs)  -- operator section 
sortedAppend xs = ((sort .) . (++)) xs  -- definition of composition 
sortedAppend = (sort .) . (++)    -- eta reduction 
+0

यह वास्तव में सहायक है, धन्यवाद – iceman

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