Haskell Language
प्रकार वर्ग
खोज…
परिचय
हास्केल में टाइपकास्टेस उस प्रकार की परिभाषा से अलग एक प्रकार से जुड़े व्यवहार को परिभाषित करने का एक साधन है। जबकि, जावा में, आप व्यवहार को टाइप की परिभाषा के भाग के रूप में परिभाषित करेंगे - अर्थात एक इंटरफ़ेस, अमूर्त वर्ग या ठोस वर्ग में - हास्केल इन दो चीजों को अलग रखता है।
हास्केल के base
पैकेज में पहले से परिभाषित कई प्रकार के टाइपकास्ट हैं। इनके बीच का संबंध नीचे दिए गए रिमार्क्स अनुभाग में चित्रित किया गया है।
टिप्पणियों
Typeclassopedia लेख से लिया गया निम्न आरेख हास्केल में विभिन्न प्रकार के किस्सों के बीच के संबंध को दर्शाता है।
शायद और फ़नकार क्लास
हास्केल में, डेटा प्रकार के कार्यों की तरह ही तर्क हो सकते हैं। उदाहरण के लिए Maybe
टाइप करें।
Maybe
एक बहुत ही उपयोगी प्रकार है जो हमें विफलता के विचार का प्रतिनिधित्व करने की इजाजत देता है, या उसके बाद। दूसरे शब्दों में, यदि कोई संभावना है कि एक संगणना विफल हो जाएगी, तो हम Maybe
वहां टाइप का उपयोग करते हैं। Maybe
अन्य प्रकारों के लिए रैपर की तरह काम करता है, जिससे उन्हें अतिरिक्त कार्यक्षमता मिलती है।
इसकी वास्तविक घोषणा काफी सरल है।
Maybe a = Just a | Nothing
क्या यह बताता है कि एक है Maybe
दो रूपों, एक में आता है Just
, जो सफलता का प्रतिनिधित्व करता है, और एक Nothing
है, जो विफलता का प्रतिनिधित्व करता है। Just
एक तर्क है जो Maybe
के प्रकार को निर्धारित करता है, और Nothing
भी Nothing
लेता है। उदाहरण के लिए, मान Just "foo"
Maybe String
, जो कि एक स्ट्रिंग प्रकार है, जो अतिरिक्त Maybe
है। मान Nothing
टाइप Maybe a
जहाँ a
भी प्रकार हो सकता है।
उन्हें अतिरिक्त कार्यक्षमता देने के लिए रैपिंग के प्रकारों का यह विचार बहुत उपयोगी है, और Maybe
अधिक से अधिक के लिए लागू होता है। अन्य उदाहरणों में Either
, IO
और सूची प्रकार शामिल हैं, प्रत्येक अलग कार्यक्षमता प्रदान करते हैं। हालांकि, कुछ क्रियाएं और क्षमताएं हैं जो इन सभी आवरण प्रकारों के लिए सामान्य हैं। इनमें से सबसे उल्लेखनीय अतिक्रमित मूल्य को संशोधित करने की क्षमता है।
इस प्रकार के प्रकारों के बारे में सोचना आम बात है जैसे कि बक्से में उन मूल्यों को रखा जा सकता है। अलग-अलग बक्से अलग-अलग मूल्य रखते हैं और अलग-अलग काम करते हैं, लेकिन कोई भी सामग्री को एक्सेस करने में सक्षम होने के बिना उपयोगी नहीं है।
इस विचार को संपुटित करने के लिए, हास्केल एक मानक typeclass नाम के साथ आता है Functor
। इसे निम्नानुसार परिभाषित किया गया है।
class Functor f where
fmap :: (a -> b) -> f a -> f b
जैसा कि देखा जा सकता है, कक्षा में दो तर्कों का एक ही कार्य, fmap
है। पहला तर्क एक प्रकार से एक फ़ंक्शन है, a
से दूसरे में, b
। दूसरा तर्क एक फंक्टर (आवरण प्रकार) है, जिसमें टाइप ए का मान होता a
। यह प्रकार b
मूल्य वाले एक फंक्शनल (आवरण प्रकार) देता है।
सरल शब्दों में, fmap
एक फ़ंक्शन लेता है और एक fmap
अंदर मूल्य पर लागू होता है। यह एक प्रकार का एकमात्र फ़ंक्शन है जो Functor
वर्ग का सदस्य होना आवश्यक है, लेकिन यह अत्यंत उपयोगी है। Functors अधिक विशिष्ट अनुप्रयोगों है कि पर काम कार्य में पाया जा सकता Applicative
और Monad
typeclasses।
टाइप क्लास इनहेरिटेंस: ऑर्ड टाइप क्लास
हास्केल वर्ग विस्तार की धारणा का समर्थन करता है। उदाहरण के लिए, वर्ग Ord
Eq
में सभी कार्यों को विरासत में मिला है, लेकिन इसके अलावा एक compare
फ़ंक्शन है जो मूल्यों के बीच एक Ordering
देता है। Ord
में सामान्य आदेश तुलना ऑपरेटर, साथ ही एक min
विधि और एक max
विधि शामिल हो सकती है।
=>
संकेतन का वही अर्थ है जो एक फ़ंक्शन हस्ताक्षर में होता है और उसे Ord
को लागू करने के लिए Eq
को लागू करने के लिए टाइप a
आवश्यकता होती है।
data Ordering = EQ | LT | GT
class Eq a => Ord a where
compare :: Ord a => a -> a -> Ordering
(<) :: Ord a => a -> a -> Bool
(<=) :: Ord a => a -> a -> Bool
(>) :: Ord a => a -> a -> Bool
(>=) :: Ord a => a -> a -> Bool
min :: Ord a => a -> a -> a
max :: Ord a => a -> a -> a
compare
निम्नलिखित सभी तरीके इसे कई तरीकों से प्राप्त कर सकते हैं:
x < y = compare x y == LT
x <= y = x < y || x == y -- Note the use of (==) inherited from Eq
x > y = not (x <= y)
x >= y = not (x < y)
min x y = case compare x y of
EQ -> x
LT -> x
GT -> y
max x y = case compare x y of
EQ -> x
LT -> y
GT -> x
टाइप कक्षाएं जो स्वयं Ord
विस्तार करती हैं, उन्हें कम से कम या तो compare
विधि (<=)
विधि को लागू करना चाहिए, जो निर्देशित विरासत जाली का निर्माण करता है।
Eq
कार्यों और IO
को छोड़कर प्रील्यू से सभी मूल डेटाटिप्स (जैसे Int
, String
, Eq a => [a]
) में Eq
उदाहरण हैं। यदि एक प्रकार Eq
तात्कालिकता करता है तो इसका मतलब है कि हम जानते हैं कि मूल्य या संरचनात्मक समानता के लिए दो मूल्यों की तुलना कैसे करें।
> 3 == 2
False
> 3 == 3
True
आवश्यक विधियाँ
-
(==) :: Eq a => a -> a -> Boolean
या(/=) :: Eq a => a -> a -> Boolean
(यदि केवल एक को लागू किया जाता है, तो दूसरा नकारात्मकता को नकारता है) परिभाषित एक)
परिभाषित करता है
-
(==) :: Eq a => a -> a -> Boolean
-
(/=) :: Eq a => a -> a -> Boolean
सीधे सुपरक्लास
कोई नहीं
उल्लेखनीय उपवर्ग
Ord
ऑर्ट को Ord
करने वाले प्रकारों में शामिल हैं, जैसे, Int
, String
, और [a]
(प्रकारों के a
जहां एक Ord a
उदाहरण)। यदि एक प्रकार Ord
तत्काल करता है, तो इसका मतलब है कि हम उस प्रकार के मूल्यों के "प्राकृतिक" ऑर्डर को जानते हैं। ध्यान दें, अक्सर एक प्रकार के "प्राकृतिक" ऑर्डर के कई संभावित विकल्प होते हैं और Ord
हमें एक का पक्ष लेने के लिए मजबूर करता है।
Ord
मानक (<=)
, (<)
, (>)
, (>=)
ऑपरेटर प्रदान करता है, लेकिन एक कस्टम बीजीय डेटा प्रकार का उपयोग करके उन सभी को दिलचस्प रूप से परिभाषित करता है
data Ordering = LT | EQ | GT
compare :: Ord a => a -> a -> Ordering
आवश्यक विधियाँ
-
compare :: Ord a => a -> a -> Ordering
या(<=) :: Ord a => a -> a -> Boolean
(मानक के डिफ़ॉल्टcompare
विधि का उपयोग करता है(<=)
इसके कार्यान्वयन में)
परिभाषित करता है
-
compare :: Ord a => a -> a -> Ordering
-
(<=) :: Ord a => a -> a -> Boolean
-
(<) :: Ord a => a -> a -> Boolean
-
(>=) :: Ord a => a -> a -> Boolean
-
(>) :: Ord a => a -> a -> Boolean
-
min :: Ord a => a -> a -> a
-
max :: Ord a => a -> a -> a
सीधे सुपरक्लास
monoid
Monoid
में दूसरों के बीच में Monoid
रिटर्न मानों के साथ सूचियां, संख्याएं और फ़ंक्शन शामिल हैं। Monoid
को Monoid
टाइप करने के लिए एक साहचर्य बाइनरी ऑपरेशन ( mappend
या (<>)
) का समर्थन करना चाहिए, जो इसके मूल्यों को जोड़ती है, और एक विशेष "शून्य" मान ( mempty
) है, जो इसके साथ एक मूल्य के संयोजन से उस मूल्य को नहीं बदलता है:
mempty <> x == x
x <> mempty == x
x <> (y <> z) == (x <> y) <> z
सहज रूप से, Monoid
प्रकार "सूची-जैसे" हैं, जिसमें वे एक साथ Monoid
मूल्यों का समर्थन करते हैं। वैकल्पिक रूप से, Monoid
प्रकारों को मूल्यों के अनुक्रम के रूप में सोचा जा सकता है जिसके लिए हम ऑर्डर के बारे में परवाह करते हैं, लेकिन समूहीकरण नहीं। उदाहरण के लिए, एक द्विआधारी पेड़ एक है Monoid
, लेकिन का उपयोग कर Monoid
संचालन हम अपनी शाखाओं में संरचना, केवल अपने मूल्यों (देखें के ट्रेवर्सल गवाह नहीं कर सकते Foldable
और Traversable
)।
आवश्यक विधियाँ
-
mempty :: Monoid m => m
-
mappend :: Monoid m => m -> m -> m
सीधे सुपरक्लास
कोई नहीं
अंक
संख्या प्रकारों के लिए सबसे सामान्य वर्ग, अधिक सटीक रूप से छल्ले , यानी संख्याएं जो सामान्य अर्थों में जोड़ी और घटाई और गुणा की जा सकती हैं, लेकिन जरूरी नहीं कि विभाजित हो।
इस वर्ग में अभिन्न प्रकार ( Int
, Integer
, Word32
आदि) और भिन्नात्मक प्रकार ( Double
, Rational
, जटिल संख्याएँ आदि) दोनों शामिल हैं। परिमित प्रकार के मामले में, अर्थ विज्ञान आम तौर पर मॉड्यूलर अंकगणितीय के रूप में समझा जाता है, यानी साथ खत्म हो और underflow †।
ध्यान दें कि संख्यात्मक वर्गों के लिए नियम मोनाड या मोनोइड कानूनों की तुलना में बहुत कम कड़ाई से पालन किए जाते हैं, या समानता की तुलना के लिए । विशेष रूप से, फ़्लोटिंग-पॉइंट नंबर आम तौर पर केवल एक अनुमानित अर्थ में कानूनों का पालन करते हैं।
विधियों
fromInteger :: Num a => Integer -> a
। एक पूर्णांक को सामान्य संख्या प्रकार में बदलें (यदि आवश्यक हो तो सीमा के चारों ओर लपेटकर)। हास्केल नंबर शाब्दिक को इसके चारों ओर सामान्य रूपांतरण के साथ एक मोनोमोर्फिकInteger
शाब्दिक के रूप में समझा जा सकता है, इसलिए आप शाब्दिक5
कोInt
संदर्भ औरComplex Double
सेटिंग दोनों में उपयोग कर सकते हैं।(+) :: Num a => a -> a -> a
। मानक जोड़, जिसे आमतौर पर साहचर्य और कम्यूटेटिव के रूप में समझा जाता है,a + (b + c) ≡ (a + b) + c a + b ≡ b + a
(-) :: Num a => a -> a -> a
। घटाव, जो इसके अतिरिक्त है:(a - b) + b ≡ (a + b) - b ≡ a
(*) :: Num a => a -> a -> a
। गुणन, एक सहयोगी ऑपरेशन जो इसके अतिरिक्त वितरित होता है:a * (b * c) ≡ (a * b) * c a * (b + c) ≡ a * b + a * c
सबसे आम उदाहरणों के लिए, गुणा भी सराहनीय है, लेकिन यह निश्चित रूप से एक आवश्यकता नहीं है।
negate :: Num a => a -> a
। अनार्य नेगेटिव ऑपरेटर का पूरा नाम।-1
नकारात्मक के लिए वाक्यविन्यास चीनी हैnegate 1
।-a ≡ negate a ≡ 0 - a
abs :: Num a => a -> a
। निरपेक्ष-मूल्य फ़ंक्शन हमेशा एक ही परिमाण का एक गैर-नकारात्मक परिणाम देता हैabs (-a) ≡ abs a abs (abs a) ≡ abs a
abs a ≡ 0
केवल तभी होना चाहिए जब shoulda ≡ 0
।वास्तविक प्रकारों के लिए यह स्पष्ट है कि गैर-नकारात्मक का क्या अर्थ है: आपने हमेशा
abs a >= 0
कोabs a >= 0
। परिसर आदि प्रकार के एक अच्छी तरह से परिभाषित आदेश की जरूरत नहीं है, तथापि का परिणामabs
हमेशा वास्तविक सबसेट ‡ (यानी एक ऐसी संख्या जो भी निषेध के बिना एक भी नंबर शाब्दिक रूप में लिखा जा सकता है देना) में होना चाहिए।signum :: Num a => a -> a
। नाम के अनुसार, साइन फ़ंक्शन, केवल-1
या1
पैदावार देता है, जो तर्क के संकेत पर निर्भर करता है। वास्तव में, यह केवल गैर-वास्तविक संख्या के लिए सच है; सामान्य रूप मेंsignum
बेहतर सामान्य समारोह के रूप में समझा जाता है:abs (signum a) ≡ 1 -- unless a≡0 signum a * abs a ≡ a -- This is required to be true for all Num instances
ध्यान दें कि हास्केल 2010 रिपोर्ट के खंड 6.4.4 में स्पष्ट रूप से किसी भी वैध
Num
उदाहरण के लिए अंतिम समानता की आवश्यकता है।
कुछ पुस्तकालयों, विशेष रूप से रैखिक और hmatrix , क्या का एक बहुत laxer समझ है Num
वर्ग के लिए है: वे सिर्फ एक रास्ता अंकगणितीय ऑपरेटर ओवरलोड के रूप में मानते हैं। हालांकि, यह +
और -
लिए बहुत सीधा है, यह पहले से ही *
और अन्य विधियों के साथ बहुत अधिक परेशानी वाला हो जाता है। उदाहरण के लिए, *
मैट्रिक्स गुणन या तत्व-वार गुणन होना चाहिए?
ऐसे गैर-संख्या उदाहरणों को परिभाषित करना एक बुरा विचार है; कृपया VectorSpace
जैसे समर्पित वर्गों पर विचार करें।
Igned विशेष रूप से, अहस्ताक्षरित प्रकारों के "नकारात्मक" बड़े सकारात्मक के चारों ओर लपेटे जाते हैं, जैसे (-4 :: Word32) == 4294967292
।
‡ यह व्यापक रूप से पूरा नहीं हुआ है: वेक्टर प्रकारों में एक वास्तविक उपसमूह नहीं है। विवादास्पद Num
के लिए इस तरह के प्रकार के आम तौर पर परिभाषित -instances abs
और signum
तत्व के लिहाज से, जो गणितीय बोल वास्तव में कोई मतलब नहीं है।