खोज…


टाइप पर्यायवाची परिवार

टाइप पर्यायवाची परिवार केवल टाइप-स्तरीय फ़ंक्शन हैं: वे पैरामीटर प्रकारों को परिणाम प्रकारों के साथ जोड़ते हैं। ये तीन अलग-अलग किस्मों में आते हैं।

बंद प्रकार-समानार्थी परिवार

ये सामान्य मूल्य-स्तरीय हास्केल कार्यों की तरह काम करते हैं: आप कुछ खंड निर्दिष्ट करते हैं, कुछ प्रकारों को मैप करते हैं:

{-# LANGUAGE TypeFamilies #-}
type family Vanquisher a where
    Vanquisher Rock = Paper
    Vanquisher Paper = Scissors
    Vanquisher Scissors = Rock

data Rock=Rock; data Paper=Paper; data Scissors=Scissors

खुले प्रकार-समानार्थी परिवार

ये टाइपकास्ट उदाहरणों की तरह अधिक काम करते हैं: कोई भी अन्य मॉड्यूल में अधिक खंड जोड़ सकता है।

type family DoubledSize w

type instance DoubledSize Word16 = Word32
type instance DoubledSize Word32 = Word64
-- Other instances might appear in other modules, but two instances cannot overlap
-- in a way that would produce different results.

वर्ग-संबद्ध प्रकार के समानार्थक शब्द

एक खुले प्रकार के परिवार को एक वास्तविक वर्ग के साथ भी जोड़ा जा सकता है। यह आमतौर पर किया जाता है, के साथ की तरह है संबद्ध डेटा परिवारों , कुछ वर्ग विधि अतिरिक्त सहायता तत्व की जरूरत है, और इन सहायता तत्व विभिन्न उदाहरणों के लिए अलग हो सकता है लेकिन संभवतः भी साझा कर सकते हैं। एक अच्छा उदाहरण VectorSpace क्लास है :

class VectorSpace v where
  type Scalar v :: *
  (*^) :: Scalar v -> v -> v

instance VectorSpace Double where
  type Scalar Double = Double
  μ *^ n = μ * n

instance VectorSpace (Double,Double) where
  type Scalar (Double,Double) = Double
  μ *^ (n,m) = (μ*n, μ*m)
  
instance VectorSpace (Complex Double) where
  type Scalar (Complex Double) = Complex Double
  μ *^ n = μ*n

ध्यान दें कि पहले दो उदाहरणों में, Scalar का कार्यान्वयन समान है। यह एक संबद्ध डेटा परिवार के साथ संभव नहीं होगा: डेटा परिवार इंजेक्टिव हैं , टाइप-समानार्थी परिवार नहीं हैं।

जबकि गैर-इंजेक्टिविटी ऊपर की तरह कुछ संभावनाएं खोलती है, यह टाइप इंफ़ेक्शन को और अधिक कठिन बना देती है। उदाहरण के लिए, निम्नलिखित टाइप नहीं करेगा:

class Foo a where
  type Bar a :: *
  bar :: a -> Bar a
instance Foo Int where
  type Bar Int = String
  bar = show
instance Foo Double where
  type Bar Double = Bool
  bar = (>0)

main = putStrLn (bar 1)

इस मामले में, कंपाइलर को यह पता नहीं चल सकता है कि किस उदाहरण का उपयोग करना है, क्योंकि bar का तर्क अपने आप में केवल एक बहुरूपी Num शाब्दिक है। और प्रकार समारोह Bar , 'उलटी दिशा "में हल नहीं किया जा सकता है ठीक है क्योंकि यह injective नहीं है और इसलिए उलटी नहीं (वहाँ के साथ अधिक से अधिक एक प्रकार हो सकता है Bar a = String )।


केवल इन दो उदाहरणों के साथ, यह वास्तव में injective है, लेकिन संकलक किसी पर बाद में अधिक उदाहरण नहीं जोड़ देगा और इस तरह व्यवहार बाधित नहीं जान सकते।

डेटाटाइप परिवार

डेटा परिवारों का उपयोग डेटाटाइप बनाने के लिए किया जा सकता है, जिनके प्रकार तर्क के आधार पर अलग-अलग कार्यान्वयन हैं।

स्टैंडअलोन डेटा परिवार

{-# LANGUAGE TypeFamilies #-}
data family List a
data instance List Char = Nil | Cons Char (List Char)
data instance List () = UnitList Int

उपरोक्त घोषणा में, Nil :: List Char , और UnitList :: Int -> List ()

संबद्ध डेटा परिवार

डेटा परिवार टाइपकास्ट के साथ भी जुड़े हो सकते हैं। यह अक्सर "हेल्पर ऑब्जेक्ट्स" के प्रकार के लिए उपयोगी होता है, जो जेनेरिक टाइपकास्ट के तरीकों के लिए आवश्यक होते हैं, लेकिन ठोस उदाहरण के आधार पर अलग-अलग जानकारी शामिल करने की आवश्यकता होती है। उदाहरण के लिए, किसी सूची में स्थानों को सूचीबद्ध करने के लिए केवल एक संख्या की आवश्यकता होती है, जबकि एक पेड़ में आपको प्रत्येक नोड पर पथ को इंगित करने के लिए एक नंबर की आवश्यकता होती है:

class Container f where
  data Location f
  get :: Location f -> f a -> Maybe a

instance Container [] where
  data Location [] = ListLoc Int
  get (ListLoc i) xs
    | i < length xs  = Just $ xs!!i
    | otherwise      = Nothing

instance Container Tree where
  data Location Tree = ThisNode | NodePath Int (Location Tree)
  get ThisNode (Node x _) = Just x
  get (NodePath i path) (Node _ sfo) = get path =<< get i sfo

Injectivity

जरूरी नहीं कि टाइप फैमिलीज इंजेक्टिव हों। इसलिए, हम किसी एप्लिकेशन से पैरामीटर का अनुमान नहीं लगा सकते हैं। उदाहरण के लिए, में servant , एक प्रकार दिया Server a हम प्रकार अनुमान नहीं लगा सकता a । इस समस्या को हल करने के लिए, हम Proxy उपयोग कर सकते हैं। उदाहरण के लिए, servant , serve का प्रकार होता है ... Proxy a -> Server a -> ... हम अनुमान लगा सकते हैं a से Proxy a क्योंकि Proxy द्वारा परिभाषित किया गया data जो injective है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow