हम तरह *
के पैरामीटर के लिए एकल, व्यापक उदाहरणों लिख सकते हैं:पैटर्न पर मिलान प्रचारित प्रकार
class MyClass d where
f :: d -> Int
instance MyClass (Maybe d) where
f _ = 3
test1 :: Maybe d -> Int
test1 x = f x
यह ठीक संकलित, और ध्यान दें कि हम एक (MyClass (हो सकता है कि घ)) ज़रूरत नहीं है पर रोके test1 क्योंकि कंपाइलर किसी भी Maybe d
के लिए मिलान करने वाला उदाहरण पाता है।
हम भी वर्ग पैरामीटर प्रकार निर्माता ये हैं के लिए एक अखिल उदाहरण लिख सकते हैं:,
class MyClass2 (a :: * -> *) where
g :: Tagged (a Int) Int
instance MyClass2 a where
g = Tagged 3
test2 :: Int
test2 = untag (g :: Tagged (Maybe Int) Int)
यह भी ठीक संकलित, और test2 एक (MyClass2 शायद) बाधा की जरूरत नहीं है क्योंकि संकलक एक पाता है मिलान उदाहरण
{-# LANGUAGE TypeOperators,
DataKinds,
KindSignatures,
GADTs,
FlexibleInstances,
FlexibleContexts,
ScopedTypeVariables #-}
import Data.Tagged
import Data.Proxy
data HList :: [*] -> * where
HNil :: HList '[]
HCons :: a -> HList as -> HList (a ': as)
class ListLen a where
len :: Tagged a Int
instance ListLen (HList '[]) where
len = Tagged 0
instance (ListLen (HList as)) => ListLen (HList (a ': as)) where
len = Tagged (1+(untag (len :: Tagged (HList as) Int)))
test3 :: Int
test3 = untag (len :: Tagged (HList '[Int, Double, Integer]) Int)
test4 :: (Proxy (HList qs)) -> Int
test4 (_ :: Proxy (HList qs)) = untag (len :: Tagged (HList qs) Int) -- error occurs here
यह त्रुटि में परिणाम है:
निम्नलिखित खिलौना कोड एक (पदोन्नत) की लंबाई की गणना सूची टाइप करने के लिए विचार करें
No instance for (ListLen (HList qs))
arising from a use of `len'
Possible fix: add an instance declaration for (ListLen (HList qs))
...
हम test4
के लिए हस्ताक्षर बाहर टिप्पणी करते हैं, तो जीएचसीआई
test4 :: (ListLen (HList qs)) => (Proxy (HList qs)) -> Int
पर टाइप करता है लेकिन यह आवश्यक नहीं होना चाहिए। जाहिर है, मैंने ListLen
के लिए उदाहरण लिखे हैं जो किसी भी कल्पनीय प्रकार की सूची से मेल खाते हैं: एक 'खाली सूची' केस, और 'विपक्ष' केस। अगर मैं ListLen
पैरामीटर को [*]
(यानी HList
रैपर ListLen
और उसके उदाहरणों में हटा दें) को बदलने के लिए ListLen
पैरामीटर को बदलता हूं तो समस्या वही बना रहता है।
हम test4
, test3
compiles बाहर टिप्पणी और ठीक चलाता है: के बाद से मैं (अनिवार्य) यह मैं कैसे निर्माण प्रकार सूची के लिए स्पष्ट वाक्य रचना ('[Int,Double,Integer]
) दे दी है, संकलक मिलान उदाहरणों को खोजने के लिए सक्षम था।
मैं कोड लिखने का प्रयास कर रहा हूं जो मेरे लिए एक प्रकार की सूची बनाता है, इसलिए मुझे स्पष्ट प्रकार की सूची वाक्यविन्यास लिखना नहीं होगा। हालांकि, ऐसा लगता है कि स्पष्ट वाक्यविन्यास का उपयोग करना एकमात्र तरीका है जीएचसी इन व्यापक उदाहरणों से मेल खाता है। शायद एक मामला है जो मुझे याद आ रही है? सिंटेक्स मैं उपयोग नहीं कर रहा हूँ?
जीएचसी को यह समझने के लिए मैं क्या कर सकता हूं कि मेरे पास [*]
की तरह सब कुछ है? मैं जीएचसी 7.4.2 का उपयोग कर रहा हूं। यह गैर-प्रचारित प्रकारों को डीकनस्ट्रक्चर करने के बारे में previous post से संबंधित हो सकता है। प्रकार के प्रचार पर पेपर here पाया जा सकता है।
शीर्षक सुझावों का स्वागत है। – crockeea
आपके पास * अलग * उदाहरण हैं, यह कोई नहीं होगा? जीएचसी को उदाहरण चुनना है, और यह एक गैर-पैरामीट्रिक ऑपरेशन है, इसलिए एक बाधा की आवश्यकता है। मुझे नहीं लगता कि आप क्या करना चाहते हैं समझ में आता है। –
जीएचसी एक स्पष्ट वर्ग बाधा का उपयोग कर रनटाइम पर * ओवरलैपिंग * उदाहरण (जो ये नहीं हैं) को हल भी कर सकता है (जो अन्यथा अनुमानित होगा)। यह क्यों नहीं देख सकता कि हमेशा * एक मैच होता है, भले ही इसे उचित उदाहरण चुनने के लिए रनटाइम तक इंतजार करना पड़े? बेशक, मैं इसे * बिना * स्पष्ट (और gratuitous) वर्ग की बाधा के लिए करने के लिए कह रहा हूं, जिसमें मेरे पास प्रदान करने की लक्जरी नहीं है। – crockeea