हास्केल में घातांक


91

कोई मुझे बता सकते हैं क्यों हास्केल प्रस्तावना घातांक (यानी के लिए दो अलग-अलग कार्यों को परिभाषित करता है ^और **)? मुझे लगा कि इस प्रकार के दोहराव को खत्म करने के लिए टाइप सिस्टम चाहिए था।

Prelude> 2^2
4
Prelude> 4**0.5
2.0

जवाबों:


130

वहाँ वास्तव में तीन घातांक ऑपरेटरों हैं: (^), (^^)और (**)^गैर-नकारात्मक अभिन्न अंग है, ^^पूर्णांक घातांक है, और **फ्लोटिंग-पॉइंट घातांक है:

(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
(**) :: Floating a => a -> a -> a

कारण प्रकार की सुरक्षा है: संख्यात्मक कार्यों के परिणाम आम तौर पर इनपुट तर्क (ओं) के समान होते हैं। लेकिन आप Intफ्लोटिंग-पॉइंट पावर को बढ़ा नहीं सकते हैं और प्रकार का परिणाम प्राप्त कर सकते हैं Int। और इसलिए टाइप सिस्टम आपको ऐसा करने से रोकता है: (1::Int) ** 0.5एक प्रकार की त्रुटि पैदा करता है। उसी के लिए जाता है (1::Int) ^^ (-1)

इसे लगाने का एक और तरीका है: Numप्रकार के तहत बंद कर दिए गए हैं ^(उन्हें गुणक व्युत्क्रम की आवश्यकता नहीं है), Fractionalप्रकार नीचे बंद हैं ^^, Floatingप्रकार नीचे बंद हैं **। चूंकि इसके लिए कोई Fractionalउदाहरण नहीं है Int, आप इसे नकारात्मक शक्ति तक नहीं बढ़ा सकते।

आदर्श रूप से, का दूसरा तर्क ^गैर-नकारात्मक होने के लिए सांख्यिकीय रूप से विवश होगा (वर्तमान में, 1 ^ (-2)एक रन-टाइम अपवाद फेंकता है)। लेकिन में प्राकृतिक संख्या के लिए कोई प्रकार नहीं है Prelude


31

हास्केल की प्रकार प्रणाली तीन घातांक ऑपरेटरों को एक के रूप में व्यक्त करने के लिए पर्याप्त शक्तिशाली नहीं है। आप वास्तव में क्या चाहते हैं कुछ इस तरह है:

class Exp a b where (^) :: a -> b -> a
instance (Num a,        Integral b) => Exp a b where ... -- current ^
instance (Fractional a, Integral b) => Exp a b where ... -- current ^^
instance (Floating a,   Floating b) => Exp a b where ... -- current **

यदि आप मल्टी-पैरामीटर टाइप क्लास एक्सटेंशन को चालू करते हैं तो भी यह वास्तव में काम नहीं करता है, क्योंकि उदाहरण के चयन के लिए हास्केल की तुलना में अधिक चतुर होने की आवश्यकता है जो वर्तमान में अनुमति देता है।


4
क्या इस बारे में बयान अभी भी लागू नहीं हो रहा है? IIRC, haskell में पहले पैरामीटर द्वारा कड़ाई से निर्धारित किए जाने वाले बहु-पैरामीटर प्रकार वर्ग के दूसरे पैरामीटर के लिए एक विकल्प है। क्या इससे परे एक और समस्या है जिसे हल नहीं किया जा सकता है?
रसेल स्टेलवर्ट

2
@ सिंग्युलर यह अभी भी सही है। पहला तर्क दूसरे को निर्धारित नहीं करता है, उदाहरण के लिए, आप चाहते हैं कि घातांक दोनों Intऔर हो Integer। उन तीन उदाहरणों की घोषणा करने में सक्षम होने के लिए इंस्टेंस रिज़ॉल्यूशन का उपयोग बैकट्रैकिंग का उपयोग करना होता है, और कोई हास्केल कंपाइलर लागू नहीं होता है।
augustss

7
क्या "प्रकार प्रणाली पर्याप्त शक्तिशाली नहीं है" तर्क अभी भी मार्च 2015 तक पकड़ में है?
एरिक कपलुन

3
आप निश्चित रूप से इसे मेरे द्वारा सुझाए गए तरीके से नहीं लिख सकते हैं, लेकिन इसे एनकोड करने का कोई तरीका हो सकता है।
15 अगस्त को

2
@ErikAllik शायद मानक हास्केल के लिए करता है, क्योंकि 2010 के बाद से कोई नई हास्केल रिपोर्ट नहीं आई है।
मार्टिन कैपोडिसी

10

यह दो ऑपरेटरों को परिभाषित नहीं करता है - यह तीन को परिभाषित करता है! रिपोर्ट से:

तीन दो-तर्क घातांक संचालन हैं: ( ^) किसी भी संख्या को एक गैर-पूर्णांक पूर्णांक शक्ति तक ^^बढ़ाता है , ( ) किसी भी पूर्णांक शक्ति को एक भिन्नात्मक संख्या बढ़ाता है, और ( **) दो फ़्लोटिंग-पॉइंट तर्क लेता है। का मान x^0या x^^0किसी के लिए 1 है x, शून्य शामिल है; 0**yअपरिभाषित है।

इसका मतलब है कि तीन अलग-अलग एल्गोरिदम हैं, जिनमें से दो सटीक परिणाम ( ^और ^^) देते हैं, जबकि **अनुमानित परिणाम देते हैं। किस ऑपरेटर का उपयोग करना है, यह चुनने के लिए कि आप कौन सा एल्गोरिदम लागू करना चाहते हैं।


4

^एक होने के लिए अपने दूसरे तर्क की आवश्यकता है Integral। यदि मैं गलत नहीं हूं, तो कार्यान्वयन अधिक कुशल हो सकता है यदि आप जानते हैं कि आप एक अभिन्न अंग के साथ काम कर रहे हैं। इसके अलावा, अगर आप कुछ चाहते हैं 2 ^ (1.234), भले ही आपका आधार अभिन्न हो, 2, आपका परिणाम स्पष्ट रूप से आंशिक होगा। आपके पास अधिक विकल्प हैं ताकि आप अपने घातांक फ़ंक्शन के प्रकारों पर अधिक तंग नियंत्रण रख सकें।

हास्केल के प्रकार की प्रणाली में अन्य प्रकार की प्रणालियों के समान लक्ष्य नहीं है, जैसे कि सी, पायथन, या लिस्प। बतख टाइपिंग (लगभग) हास्केल मानसिकता के विपरीत है।


4
मैं पूरी तरह से सहमत नहीं हूं कि हास्केल टाइप मानसिकता बतख टाइपिंग के विपरीत है। हास्केल प्रकार की कक्षाएं बतख टाइपिंग की तरह काफी हैं। class Duck a where quack :: a -> Quackपरिभाषित करता है कि हम एक बतख की क्या उम्मीद करते हैं, और फिर प्रत्येक उदाहरण कुछ निर्दिष्ट करता है जो बतख की तरह व्यवहार कर सकता है।
अगस्त

9
@ उद्घाटन यह देखें कि आप कहां से आ रहे हैं। लेकिन बत्तख टाइपिंग के पीछे अनौपचारिक आदर्श वाक्य है "यदि यह बतख की तरह दिखता है, बतख की तरह कार्य करता है, और बतख की तरह चुटकी लेता है, तो यह बतख है।" हास्केल में, यह एक बतख नहीं है जब तक कि इसे एक उदाहरण घोषित नहीं किया जाता है Duck
डैन बर्टन

1
यह सच है, लेकिन यही मैं हास्केल से उम्मीद करूंगा। आप एक बतख चाहते हैं कुछ भी कर सकते हैं, लेकिन आपको इसके बारे में स्पष्ट होना चाहिए। हम कुछ गलती नहीं करना चाहते हैं जिसे हमने बतख के लिए नहीं कहा है।
अगस्त २०'११

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

आपके पास मिश्रित बतख की एक सूची हो सकती है, लेकिन आपको अस्तित्ववादी मात्रा का विस्तार की आवश्यकता है।
बोलपत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.