2010-09-18 23 views
10

मैं हास्केल के बारे में पढ़ रहा हूं और मुझे यह समझने में कठिनाई हो रही है कि इस भाषा में फ़ंक्शन परिभाषाओं को कैसे प्रबंधित किया जाता है।क्यों x x प्रकार का प्रकार है (संख्या ए) => ए -> ए -> हास्केल में?

चलो कहते हैं कि मैं एक sum समारोह को परिभाषित कर रहा हूँ करते हैं:

let sum x y = x + y 

अगर मैं अपने प्रकार के लिए हास्केल क्वेरी

:t sum 

मैं

sum :: (Num a) => a -> a -> a 
  1. इसका क्या मतलब है => ऑपरेटर? क्या लैम्ब्डा अभिव्यक्तियों के साथ इसका कोई संबंध नहीं है? इस प्रकार एक संकेत है कि => ऑपरेटर का पालन करने वाला क्या है, सी # में।
  2. a -> a -> a का अर्थ क्या है? कई अलग-अलग कार्यों पर आंखों के निरीक्षण से मैं कोशिश कर रहा हूं, ऐसा लगता है कि प्रारंभिक a -> a तर्क हैं और अंतिम -> a योग फ़ंक्शन का परिणाम है। यदि यह सही है, तो (a, a) -> a के रूप में कुछ क्यों नहीं, जो कि अधिक सहज ज्ञान युक्त लगता है?
+12

यदि आप चाहते हैं करने के लिए: एक फंक्शन फॉर्म (a,b,c,...)->z डिफ़ॉल्ट रूप से में लिखा है

plusFourToList :: Num a => [a] -> [a] plusFourToList = map (plus 4) 

, तो हम lambdas का एक बहुत लागू करने के लिए होता है हास्केल को समझें, आपको भाषा के हर हिस्से के बारे में SO पूछने के बजाय बेहतर (अच्छा) परिचय मिलता है। http://stackoverflow.com/questions/1012573/how-to-learn-haskell/1016986#1016986 कुछ अच्छे संसाधनों के लिंक और आगे की सलाह है। – delnan

उत्तर

29

0. हास्केल => साथ कोई संबंध नहीं है सी # के =>।हास्केल में एक गुमनाम समारोह,

\x -> x * x 

इसके अलावा के साथ बनाई गई है समारोह sum नाम नहीं है क्योंकि such a function पहले से ही प्रस्तावना में मौजूद है। भ्रम से बचने के लिए अब इसे plus पर कॉल करें।

1. वैसे भी, => हास्केल में इस प्रकार का संदर्भ प्रदान करता है। उदाहरण के लिए:

show :: (Show a) => a -> String 

यहाँ, Show a => मतलब है a प्रकार प्रकार वर्गShow, a एक स्ट्रिंग के लिए परिवर्तनीय होना चाहिए जिसका मतलब है का एक उदाहरण होना चाहिए। इसी तरह, (Num a) => a -> a -> a का अर्थ है a प्रकार टाइप क्लास नाम का एक उदाहरण होना चाहिए, जिसका अर्थ है a एक संख्या की तरह होना चाहिए। यह a पर एक बाधा डालता है ताकि show या plus कुछ असमर्थित इनपुट स्वीकार नहीं करेगा, उदा। plus "56" "abc"। (स्ट्रिंग एक संख्या की तरह नहीं है।)

एक प्रकार का वर्ग सी # के इंटरफ़ेस के समान है, या अधिक विशेष रूप से, interface base-type constraint in generics। अधिक जानकारी के लिए प्रश्न Explain Type Classes in Haskell देखें।

2.a -> a -> a का अर्थ a -> (a -> a) है। इसलिए, यह वास्तव में एक असामान्य कार्य है जो एक और कार्य देता है।

plus x = \y -> x + y 

यह आंशिक अनुप्रयोग (करीना) बहुत आसान बनाता है। आंशिक आवेदन बहुत esp का उपयोग किया जाता है। उच्च आदेश कार्यों का उपयोग करते समय। उदाहरण के लिए हम

map (plus 4) [1,2,3,4] 

सूची के प्रत्येक तत्व में 4 जोड़ने के लिए उपयोग कर सकते हैं। वास्तव में हम फिर से परिभाषित करने के लिए आंशिक आवेदन इस्तेमाल कर सकते हैं:

plusFourToList = \l -> map(\y -> plus(4,y), l) 
+2

अच्छा जवाब, सिवाय इसके कि मैं हमेशा क्रिंग करता हूं जब मैं किसी को यह कहता हूं कि टाइप क्लास इंटरफ़ेस कक्षाओं की तरह हैं। उनके पास कुछ हद तक समान भूमिका है, लेकिन उस समानता से तर्क आपको गंभीरता से भटक देगा। विशेष रूप से हास्केल में एक प्रकार का वर्ग स्वयं एक प्रकार नहीं है, इसलिए आप संख्याओं की सूची के लिए "[न्यूम]" नहीं लिख सकते हैं। –

+2

हालांकि लेखन (संख्या ए) => [ए] वास्तव में इतना अलग नहीं है। मेरा मानना ​​है कि, जब तक आप यह स्पष्ट करते हैं कि इंटरफ़ेस समानता शुरू करने में आपकी सहायता करने के लिए केवल एक सरल है, ठीक है। –

+1

भले ही सी # में 'न्यू' इंटरफेस था, 'सूची ' जैसी कुछ अभी भी '(संख्या ए) => [ए] 'से काफी अलग है, क्योंकि' [5 :: Int, 3.5 :: Double] 'नहीं है हास्केल में टाइप '(संख्या ए) => [ए] 'का वैध मान। मुझे लगता है कि यह बहुत से लोगों को आश्चर्यचकित करता है जब वे पहली बार टाइप क्लास देखते हैं। – hzap

4

की वजह से के बजाय a -> a -> a है। मजेदार तथ्य: घुमावदार (पुनः) आस्केल करी द्वारा आविष्कार किया गया था! असल में इसका मतलब है कि यदि आप एक एक तर्क की आपूर्ति करते हैं तो आप योग का आंशिक आवेदन, a -> a प्रकार का एक और कार्य वापस प्राप्त करेंगे।

+0

विकिपीडिया लेख के परिचय को पढ़ने के बाद भी, मुझे नहीं मिल सकता है कि करीबी बिंदु क्या है :( –

+1

मुझे बिंदु नहीं मिलता है! यह उन चीजों में से एक है जो आप कार्यात्मक प्रोग्रामिंग में करते हैं ... – fredley

+2

आप काम करते हैं ताकि आप आंशिक रूप से उन्हें लागू कर सकें। सूची में प्रत्येक तत्व को 3 जोड़ना चाहते हैं? कोई समस्या नहीं! - नक्शा (+3) [1, 2, 3, 4, 5] – Paul

5

Num a => का अर्थ है "निम्नलिखित में, a टाइप प्रकार Num" (जो कि प्रकार के प्रकार के लिए इंटरफ़ेस की तरह है) का एक उदाहरण देखेंगे।

=> ऑपरेटर प्रकार के "बॉडी" से "टाइपक्लास बाधाओं" को अलग करता है। यह सी # में सामान्य बाधाओं के लिए where ऑपरेटर की तरह है। आप इसे तार्किक निहितार्थ के रूप में पढ़ सकते हैं जैसे कि "अगर a एक संख्यात्मक प्रकार है तो sum का उपयोग a -> a -> a प्रकार के साथ किया जा सकता है"।

a -> a -> a "एक समारोह है कि एक a लेता है और एक समारोह है जो एक a लेता है और एक a रिटर्न देता है" का मतलब है। इसके लिए आपको समझने की आवश्यकता है कि sum x y पार्स (sum x) y के रूप में पार्स करें।

दूसरे शब्दों में: आप पहले sum पर x तर्क के साथ कॉल करते हैं। फिर आप a -> a प्रकार का एक नया फ़ंक्शन वापस प्राप्त करें। फिर आप y तर्क के साथ उस फ़ंक्शन को कॉल करते हैं और अब आप a टाइप करें, जहां ax और y का प्रकार है और Num टाइपक्लास का उदाहरण होना चाहिए।

यदि आप sum टाइप Num a => (a,a) -> a टाइप करने के लिए चाहते हैं, तो आप इसे sum (x,y) = x+y के रूप में परिभाषित कर सकते हैं। इस मामले में आपके पास एक फ़ंक्शन होता है जिसमें दो a एस युक्त टुपल होता है और a (जहां a फिर से Num टाइपक्लास का उदाहरण है) देता है।

हालांकि "करी शैली" (कार्यों लौटने कार्यों से अधिक पैरामीटर अनुकरण करने के लिए) और अधिक अक्सर टपल शैली की तुलना में प्रयोग किया जाता है, क्योंकि यह आप आसानी से आंशिक रूप से कार्यों को लागू करने के लिए अनुमति देता है। उदाहरण map (sum 5) [1,2,3]। यदि आपने sum को टुपल के साथ परिभाषित किया था, तो आपको map (\y -> sum 5 y) [1,2,3] करना होगा।

10

इसका कारण यह है

हास्केल में हर समारोह एक एकल पैरामीटर लेता है और एक एकल मान

एक समारोह एकाधिक मूल्य लेने के लिए की जरूरत है देता है, समारोह एक curried हो गया होता फ़ंक्शन या इसे एकल ट्यूपल लेना होगा।

हम एक कोष्ठक जोड़ते हैं, तो फ़ंक्शन हस्ताक्षर हो जाता है:

sum :: (Num a) => a -> (a -> a) 

हास्केल में, समारोह हस्ताक्षर: A -> B एक समारोह समारोह के "डोमेन" A है और समारोह के "Codomain" का अर्थ है B है; या प्रोग्रामर की भाषा में, फ़ंक्शन A प्रकार का पैरामीटर लेता है और B प्रकार का मान देता है।

इसलिए, फ़ंक्शन परिभाषा sum :: Num -> (Num -> Num) का अर्थ है योग "एक ऐसा फ़ंक्शन है जो a प्रकार का पैरामीटर लेता है और Num -> Num प्रकार का फ़ंक्शन देता है"।

असल में, इससे करी/आंशिक कार्य होता है।

currying की अवधारणा हास्केल तरह कार्यात्मक भाषाओं में आवश्यक है, क्योंकि आप की तरह काम करने के लिए चाहते हैं:

map (sum 5) [1, 2, 3, 5, 3, 1, 3, 4] -- note: it is usually better to use (+ 5) 

कि कोड में, (राशि 5), एक समारोह है कि एक एकल पैरामीटर लेता है यह फ़ंक्शन (योग 5) सूची में प्रत्येक आइटम के लिए बुलाया जाएगा, उदाहरण के लिए ((राशि 5) 1) रिटर्न 6.

तो sumsum :: (Num, Num) -> Num की एक हस्ताक्षर किया था, तो योग एक ही समय में अपने पैरामीटर के दोनों प्राप्त करने के लिए, क्योंकि अब योग एक "समारोह है कि एक tuple (Num, Num) प्राप्त करता है और एक रिटर्न है होता Num "।

अब, दूसरा प्रश्न, Num a => a -> a का क्या अर्थ है? यह मूल रूप से यह कहने के लिए एक शॉर्टेंड है कि प्रत्येक बार जब आप हस्ताक्षर में a देखते हैं, तो उसे नम या इसके व्युत्पन्न वर्ग में से एक के साथ बदलें।

+2

आप नोटेशन का थोड़ा सा दुरुपयोग कर रहे हैं: 'न्यू' एक टाइपक्लास है, एक प्रकार नहीं। – dave4420

4

हास्केल दस्तावेज इसके बारे में बहुत स्पष्ट नहीं है, लेकिन (संख्या ए) => का अर्थ है कि फ़ंक्शन उन सभी मामलों के लिए काम करता है जहां कोई संख्या है या इससे प्राप्त होता है (इसलिए एक संख्या है)।

यह भी देखें: http://www.cse.unsw.edu.au/~en1000/haskell/inbuilt.html

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