कोई मुझे बता सकते हैं क्यों हास्केल प्रस्तावना घातांक (यानी के लिए दो अलग-अलग कार्यों को परिभाषित करता है ^
और **
)? मुझे लगा कि इस प्रकार के दोहराव को खत्म करने के लिए टाइप सिस्टम चाहिए था।
Prelude> 2^2
4
Prelude> 4**0.5
2.0
कोई मुझे बता सकते हैं क्यों हास्केल प्रस्तावना घातांक (यानी के लिए दो अलग-अलग कार्यों को परिभाषित करता है ^
और **
)? मुझे लगा कि इस प्रकार के दोहराव को खत्म करने के लिए टाइप सिस्टम चाहिए था।
Prelude> 2^2
4
Prelude> 4**0.5
2.0
जवाबों:
वहाँ वास्तव में तीन घातांक ऑपरेटरों हैं: (^)
, (^^)
और (**)
। ^
गैर-नकारात्मक अभिन्न अंग है, ^^
पूर्णांक घातांक है, और **
फ्लोटिंग-पॉइंट घातांक है:
(^) :: (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
।
हास्केल की प्रकार प्रणाली तीन घातांक ऑपरेटरों को एक के रूप में व्यक्त करने के लिए पर्याप्त शक्तिशाली नहीं है। आप वास्तव में क्या चाहते हैं कुछ इस तरह है:
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 **
यदि आप मल्टी-पैरामीटर टाइप क्लास एक्सटेंशन को चालू करते हैं तो भी यह वास्तव में काम नहीं करता है, क्योंकि उदाहरण के चयन के लिए हास्केल की तुलना में अधिक चतुर होने की आवश्यकता है जो वर्तमान में अनुमति देता है।
Int
और हो Integer
। उन तीन उदाहरणों की घोषणा करने में सक्षम होने के लिए इंस्टेंस रिज़ॉल्यूशन का उपयोग बैकट्रैकिंग का उपयोग करना होता है, और कोई हास्केल कंपाइलर लागू नहीं होता है।
यह दो ऑपरेटरों को परिभाषित नहीं करता है - यह तीन को परिभाषित करता है! रिपोर्ट से:
तीन दो-तर्क घातांक संचालन हैं: (
^
) किसी भी संख्या को एक गैर-पूर्णांक पूर्णांक शक्ति तक^^
बढ़ाता है , ( ) किसी भी पूर्णांक शक्ति को एक भिन्नात्मक संख्या बढ़ाता है, और (**
) दो फ़्लोटिंग-पॉइंट तर्क लेता है। का मानx^0
याx^^0
किसी के लिए 1 हैx
, शून्य शामिल है;0**y
अपरिभाषित है।
इसका मतलब है कि तीन अलग-अलग एल्गोरिदम हैं, जिनमें से दो सटीक परिणाम ( ^
और ^^
) देते हैं, जबकि **
अनुमानित परिणाम देते हैं। किस ऑपरेटर का उपयोग करना है, यह चुनने के लिए कि आप कौन सा एल्गोरिदम लागू करना चाहते हैं।
^
एक होने के लिए अपने दूसरे तर्क की आवश्यकता है Integral
। यदि मैं गलत नहीं हूं, तो कार्यान्वयन अधिक कुशल हो सकता है यदि आप जानते हैं कि आप एक अभिन्न अंग के साथ काम कर रहे हैं। इसके अलावा, अगर आप कुछ चाहते हैं 2 ^ (1.234)
, भले ही आपका आधार अभिन्न हो, 2, आपका परिणाम स्पष्ट रूप से आंशिक होगा। आपके पास अधिक विकल्प हैं ताकि आप अपने घातांक फ़ंक्शन के प्रकारों पर अधिक तंग नियंत्रण रख सकें।
हास्केल के प्रकार की प्रणाली में अन्य प्रकार की प्रणालियों के समान लक्ष्य नहीं है, जैसे कि सी, पायथन, या लिस्प। बतख टाइपिंग (लगभग) हास्केल मानसिकता के विपरीत है।
class Duck a where quack :: a -> Quack
परिभाषित करता है कि हम एक बतख की क्या उम्मीद करते हैं, और फिर प्रत्येक उदाहरण कुछ निर्दिष्ट करता है जो बतख की तरह व्यवहार कर सकता है।
Duck
।