2015-10-11 5 views
6

मैं निम्नलिखित समारोह परिभाषा करने की कोशिश कीइस बिंदु को मुक्त परिभाषा क्यों हास्केल में काम नहीं करती है?</p> <pre><code>relativelyPrime x y = gcd x y == 1 </code></pre> <p>बिंदु से मुक्त:

relativelyPrime = (== 1) . gcd 

बहरहाल, यह मुझे निम्न त्रुटि देता है:

Couldn't match type ‘Bool’ with ‘a -> Bool’ 
Expected type: (a -> a) -> a -> Bool 
    Actual type: (a -> a) -> Bool 
Relevant bindings include 
    relativelyPrime :: a -> a -> Bool (bound at 1.hs:20:1) 
In the first argument of ‘(.)’, namely ‘(== 1)’ 
In the expression: (== 1) . gcd 
In an equation for ‘relativelyPrime’: 
    relativelyPrime = (== 1) . gcd 

मैं नहीं काफी समझना। gcd दो इंट्स/इंटीजर लेता है, एक इंट्स/इंटीजर देता है, फिर एक इंट/इंटीजर की समानता के लिए '1' की जांच की जाती है। मुझे नहीं पता कि मेरी त्रुटि कहां है।

+4

अच्छी तरह से 'gcd' एक और समारोह का उत्पादन करेगा अगर केवल एक ही तर्क दिया - और अपने point- में मुफ्त संस्करण जिसे आप इस * फ़ंक्शन * को '(== 1)' पर रखते हैं, जो निश्चित रूप से फ़ंक्शंस को प्रबंधित करने के बारे में नहीं जानता है;) – Carsten

+2

शायद आप समझते हैं कि जब आप पहले * एक * बिंदु * हटाते हैं: 'सापेक्षप्रिम x = (= = 1)। जीसीडी एक्स' यह काम करता है!अब आप नहीं * हटाने * 'अब x' कर सकते हैं के रूप में यह * * करने के लिए' gcd' तेजी से जुड़ा हुआ है - आप सकता है अगर आप था '(== 1) $ gcd x' – Carsten

+1

@ कार्स्टन की टिप्पणी सही है। एक विकल्प का उपयोग करने के '' gcd' एक एकल तर्क समारोह में बदलने के लिए uncurry' (दो पूर्णांकों का टपल लेने) होगा। – psmears

उत्तर

7

यह काम नहीं करता है क्योंकि gcd को दो इनपुट की आवश्यकता होती है जबकि फ़ंक्शन संरचना केवल gcd एक इनपुट प्रदान करती है। समारोह रचना की परिभाषा पर विचार करें:

f . g = \x -> f (g x) 

इसलिए, अभिव्यक्ति (== 1) . gcd के बराबर है:

\x -> (== 1) (gcd x) 

यह आप क्या चाहते हैं नहीं है। आप चाहते हैं:

\x y -> (== 1) (gcd x y) 

आप एक द्विआधारी समारोह के साथ एक एकल समारोह की रचना करने के लिए एक नया ऑपरेटर निर्धारित कर सकते हैं:

f .: g = \x y -> f (g x y) 

फिर, अपनी अभिव्यक्ति हो जाता है:

relativelyPrime = (== 1) .: gcd 

वास्तव में, (.:) ऑपरेटर को फ़ंक्शन संरचना के संदर्भ में परिभाषित किया जा सकता है:

(.:) = (.) . (.) 

यह एक उल्लू की तरह दिखता है, लेकिन वे वास्तव में समकक्ष हैं। इस प्रकार, एक और तरीका अभिव्यक्ति लिखने के लिए:

relativelyPrime = ((== 1) .) . gcd 

आप को समझने के लिए क्या हो रहा है तो देखना चाहते हैं: What does (f .) . g mean in Haskell?

5

उस पर टिप्पणी के रूप में - यदि आप वास्तव में एक बिंदु मुक्त संस्करण चाहते हैं तो आपको पहले uncurry gcd का प्रयोग कर एक संस्करण है कि एक ही इनपुट स्वीकार करता है (एक टपल) में gcd को बदलने के लिए कर सकते हैं:

Prelude> :t uncurry gcd 
uncurry gcd :: Integral c => (c, c) -> c 

तो साथ जांच (== 1) और अंत में मूल हस्ताक्षर के लिए इसे फिर से curry:

relativeelyPrime = curry ((== 1) . (uncurry gcd)) 

अपने संस्करण सिर्फ इसलिए gcd काम नहीं किया है, तो केवल पहला तर्क दिया एक समारोह का उत्पादन और यह (== 1) के लिए कोई कानूनी इनपुट नहीं है जो एक संख्या का इंतजार कर रहा है।

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