2012-08-03 13 views
6

मैं Data.Has के स्रोत कोड को देख रहा था और यह पता लगाने की कोशिश कर रहा हूं कि यह कैसे काम करता है। मेरा मानना ​​है कि निम्नलिखित कोड का उद्देश्य किसी व्यक्ति को और b :: B को एक नए मान में "जुड़ने" की अनुमति देने के लिए है, जिसमें a और b दोनों की कार्यक्षमता है।कक्षा और उदाहरण घोषणाओं में कीवर्ड टाइप करें

मुझे विशेष रूप से समझ में नहीं आता कि type का अर्थ कक्षा और उदाहरण घोषणाओं के अंदर है।

मुझे यह भी नहीं पता कि ~ प्रतीक का अर्थ नीचे क्या है।

क्या कोई Data.Has.TypeList से नीचे दिए गए कोड को समझा सकता है?

-- | Provides type-list functionality 

module Data.Has.TypeList where 

import Control.Applicative 
import Data.Monoid (Monoid (..)) 
import Test.QuickCheck (Arbitrary (..), CoArbitrary (..)) 
import Data.Typeable 
import Data.Data 
-- | Cons a type onto type-list. 
data a ::: b = a ::: b deriving (Show,Eq,Ord,Read,Bounded,Typeable,Data) 

-- | The empty type-list. 
data TyNil = TyNil deriving (Read,Typeable,Data) 

-- | Appends a type-list and another. 
class Append a b where 
    type a :++: b 
    (.++.) :: a -> b -> a :++: b 
infixr 5 :++: 

-- Implementation of Append 

instance Append TyNil b where 
    type TyNil :++: b = b 
    _ .++. b = b 

instance (Append y b) => Append (x ::: y) b where 
    type (x ::: y) :++: b = x ::: (y :++: b) 
    ~(x ::: y) .++. b = x ::: (y .++. b) 
+0

उन्हें संबंधित प्रकार समानार्थी कहा जाता है। ये संरचनाएं कार्यात्मक निर्भरताओं के समान हैं लेकिन संबंधों के बजाय प्रकार के कार्यों का उपयोग करें। –

उत्तर

7

type typeclass और उदाहरण घोषणाओं के अंदर वाक्य रचना TypeFamilies विस्तार का एक हिस्सा है। टाइप परिवारों को प्रकारों से प्रकारों के रूप में माना जा सकता है। हास्केल विकी में टाइप और डेटा परिवारों का एक विस्तृत विस्तृत स्पष्टीकरण है (लिंक देखें)।

कक्षाओं को टाइप करने के लिए लागू, परिवार संबंधित प्रकार बनें। इस संबंध में वे FunctionalDependencies के बहुत करीब हैं, यानी, वे अनजान इंस्टेंस रिज़ॉल्यूशन की अनुमति देते हैं। इसकी आवश्यकता को in the GHC manual समझाया गया है।

आपके उदाहरण में टाइप परिभाषाएं बहुत सरल हैं। ::: 2-टुपल (मानों की एक जोड़ी) के लिए एक और नाम है, और TyNil इकाई प्रकार () पर isomorphic है।

मैं कक्षा और उदाहरण घोषणा को पढ़ने की कोशिश करूंगा ताकि यह स्पष्ट हो सके कि उनका क्या मतलब है।

class Append a b where 
    type a :++: b 
    (.++.) :: a -> b -> a :++: b 
infixr 5 :++: 

प्रचार एक संबद्ध प्रकार a :++: b और एक विधि समारोह (.++.) जो प्रकार a और b के मानों का उपयोग करके प्रकार a :++: b के एक मूल्य की पैदावार के साथ Append a b typeclass multiparameter। हम यह भी (.++.) सेट प्राथमिकता के साथ सही-साहचर्य होने के लिए 5.

instance Append TyNil b where 
    type TyNil :++: b = b 
    _ .++. b = b 

निश्चित पहले पैरामीटर (TyNil) और मनमाने ढंग से दूसरा पैरामीटर (b), जहां प्रकार a :++: b जुड़े साथ Append a b का एक उदाहरण घोषित (में इस मामले में यह TyNil :++: b है) को b के बराबर घोषित किया गया है। (मैं वर्णन नहीं करूंगा कि कौन सी विधि है, यह काफी स्पष्ट है)।

instance (Append y b) => Append (x ::: y) b where 
    type (x ::: y) :++: b = x ::: (y :++: b) 
    ~(x ::: y) .++. b = x ::: (y .++. b) 

मनमाना x और y और मनमाने ढंग से दूसरा पैरामीटर b दिया पहले से ही है कि वहाँ घोषित Append y b का एक उदाहरण के लिए प्रपत्र x ::: y में पहली पैरामीटर के साथ Append a b का एक उदाहरण घोषित। एसोसिएटेड प्रकार a :++: b (यहां (x ::: y) :++: b, स्पष्ट रूप से) x ::: (y :++: b) के बराबर घोषित किया गया है।विधि परिभाषा यहां भी स्पष्ट है: यह मानों की एक जोड़ी और एक और मूल्य लेता है और एक और जोड़ी बनाता है जहां पहला तत्व पहले तर्क में समान होता है और दूसरा तत्व .++. विधि के साथ दूसरे तर्क के साथ पहले तर्क से दूसरा तत्व होता है। हम Append y b बाधा

की वजह से .++. उपयोग करने के लिए अनुमति दी जाती है ये वर्ग घोषणा और उदाहरण घोषणाओं में (.++.) विधि के प्रकार हस्ताक्षर कर रहे हैं:

(.++.) ::    a  -> b -> a :++: b 
(.++.) ::    TyNil -> b -> b 
(.++.) :: Append y b => x ::: y -> b -> x ::: (y :++: b) 

नोट प्रत्येक उदाहरण के बहुत सार a :++: b में करने के लिए और अधिक ठोस प्रकार बदल देती है कि । यह पहले मामले में b और अधिक जटिल x ::: (y :++: b) है, जो :++: के संदर्भ में लिखा गया है। जुड़े प्रकार के

इस तरह की घोषणा वहाँ कुछ प्रकार (a :++: b इस मामले में) है कि प्रकार प्रणाली बताने के लिए जो है विशिष्ट a और b अकेले द्वारा निर्धारित की जरूरत है। यही कारण है, typechecker जानता है कि कुछ अभिव्यक्ति में a और b प्रकार के लिए, कहते हैं, Int और Double बराबर हैं, और अगर है:

  1. की कोई समस्या Append a b है;
  2. वहाँ type Int :++: Double = String के रूप में, एक प्रकार वर्ग उदाहरण Append Int Double जुड़े प्रकार की घोषणा की, कहते हैं के साथ है,

तो typechecker पता चल जाएगा कि वह प्रकार a :++: b को पूरा करता है, तो यह पता चलेगा कि वास्तव में इस प्रकार के String है।

~ के लिए, इसे 'आलसी पैटर्न मिलान' कहा जाता है। यह बहुत स्पष्ट रूप से समझाया गया है here

यह पूछने के लिए स्वतंत्र महसूस करें कि कुछ अभी भी स्पष्ट नहीं है।

संबंधित मुद्दे