2011-12-23 9 views
10

मैं एक समारोह है कि एक सूची है कि किसी भी विधेय को संतुष्ट में तत्वों की संख्या की गणना करता है परिभाषित करना चाहते हैं की संख्याpointfree शैली में हास्केल में तत्वों

number_of_elements (==2) [2,1,54,1,2] 

चाहिए वापसी ।

हम इसे लिख सकते हैं कम:

number_of_elements f = length . filter f 

क्या यह संभव है पैरामीटर के बिना यह लिखने के लिए?

+3

अपने लिए "Pointfree शैली" कहा जाता है क्या देख रहे हैं। इसके बारे में यहां एक विकी है: http://www.haskell.org/haskellwiki/Pointfree। यह आपको उल्लू की तरह सभी चाल सिखाता है: '((।) $ (।)) 'और डॉट:' ((।)। (।)) '। हालांकि मैं व्यक्तिगत रूप से इस शैली की सिफारिश नहीं करता। –

+6

मैं यह देखने के लिए थोड़ा सा खेल रहा हूं कि यह कैसे काम करता है, लेकिन आंशिक रूप से पॉइंटफ्री शैली 'number_of_elements f = length का उपयोग करके। फिल्टर एफ'। यह आमतौर पर सबसे अधिक पठनीय है। –

+6

यह एक ऐसा कार्य है जिसे मैं शायद ही कभी परिभाषित करना परेशान करता हूं, क्योंकि 'लंबाई (फ़िल्टर एफ एक्सएस) 'स्पष्ट रूप से,' number_of_elements f xs' से पढ़ने के लिए आसान है। उत्तरार्द्ध के लिए मुझे यह समझने की आवश्यकता है कि आपका कार्य आपकी कार्य परिभाषा, दस्तावेज़ीकरण या इसे प्रकार से कहकर देखकर क्या करता है; जबकि पूर्व दो कार्यों के एक सीधा संयुक्त उपयोग है जो मैं पहले से समझता हूं-और यह लिखने के लिए भी छोटा है! मैं इसे केवल 'जहां' बाध्यकारी, या एक अप्रत्याशित मॉड्यूल फ़ंक्शन के रूप में एक सहायक फ़ंक्शन के रूप में परिभाषित करता हूं- और तब भी तभी होता है जब यह अन्य कार्यों के लिए तर्क हो। –

उत्तर

17

ज़रूर है:

number_of_elements = (length .) . filter 
+17

हां, यह उचित पॉइंटफ्री, अपठनीय शैली है :) –

+0

धन्यवाद, और आप समझा सकते हैं कि क्यों '(लंबाई। फ़िल्टर) 'या' (लंबाई $ फ़िल्टर)' काम नहीं करेगा? – vikingsteve

+1

@vikingsteve, ठीक है, 'लंबाई। fitler' 'x -> लंबाई (फ़िल्टर x) 'तक फैलता है। यहां 'फ़िल्टर x' एक फ़ंक्शन है और आप किसी फ़ंक्शन की लंबाई की गणना नहीं कर सकते हैं, जो भी इसका मतलब होगा। इसी तरह, 'लंबाई $ फ़िल्टर'' फ़िल्टर' फ़ंक्शन की लंबाई की गणना करने का प्रयास कर रहा है। – Rotsor

12

मुझे नहीं लगता कि आप अधिक से अधिक पठनीय आप क्या सुझाव प्राप्त कर सकते हैं करते हैं। हालांकि, सिर्फ मनोरंजन के लिए आप यह कर सकते हैं:

numberOfElements = (.) (.) (.) length filter 

या

(.:) = (.) . (.) 
numberOfElements = length .: filter 
+3

'(। *) 'आमतौर पर' (। :) 'कहा जाता है; [lambdabot] (http://www.haskell.org/haskellwiki/Lambdabot) उदाहरण के लिए, इसे कॉल करता है। – ehird

+0

@ehird ने इसे बदल दिया, धन्यवाद। – is7s

+2

क्यों fmap fmap fmap' fmap नहीं? –

7

शायद आप निम्न पसंद Semantic Editor Combinators के बारे में पढ़ने के लिए। वहाँ से result Combinator लें:

result :: (output -> output') -> (input -> output) -> (input -> output') 
result = (.) 

result Combinator एक समारोह लेता है और एक अन्य फ़ंक्शन के परिणाम पर यह लागू होता है। अब उन कार्यों को देखकर हमने:

filter :: (a -> Bool) -> [a] -> [a] 
length :: [a] -> Int 

अब, length[a] के लिए लागू होता है; जो, ऐसा होता है, परिणाम foo :: [a] -> [a] के परिणाम का परिणाम है। तो,

result length :: ([a] -> [a]) -> ([a] -> Int) 

लेकिन filter का परिणाम वास्तव में एक [a] -> [a] समारोह है, इसलिए हम filter के परिणाम के result length लागू करना चाहते हैं:

number_of_elements = result (result length) filter 
+1

मैं तैयार एसईसी (अर्थात् संपादक संपादक) को अलग करने के लिए उस अंतिम पंक्ति को फिर से लिखूंगा: 'number_of_elements = (result.result) लंबाई फ़िल्टर'। इस प्रकार पढ़ें: 'फ़िल्टर' के परिणाम के परिणामस्वरूप 'लंबाई' लागू करके तत्वों की संख्या की गणना करें। यहां '(result.result) 'संपादक संयोजक है और' लंबाई' (अर्थात्) संपादक है। निश्चित रूप से [एसईसी पोस्ट] (http://conal.net/blog/posts/semantic-editor-combinators) पढ़ें। – Conal

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