2012-04-17 16 views
26

मौजूदा प्रकारों का उपयोग करते समय, हमें forall एड मान निकालने के लिए पैटर्न-मिलान सिंटैक्स का उपयोग करना होगा। हम साधारण रिकॉर्ड चयनकर्ताओं को कार्यों के रूप में उपयोग नहीं कर सकते हैं। GHC एक त्रुटि रिपोर्ट करता है और yALL की इस परिभाषा के साथ पैटर्न मिलान उपयोग करने का सुझाव:मैं अस्तित्व में क्वांटिफाइड प्रकार के साथ रिकॉर्ड चयनकर्ता का उपयोग क्यों नहीं कर सकता?

{-# LANGUAGE ExistentialQuantification #-} 

data ALL = forall a. Show a => ALL { theA :: a } 
-- data ok 

xALL :: ALL -> String 
xALL (ALL a) = show a 
-- pattern matching ok 

-- ABOVE: heaven 
-- BELOW: hell 

yALL :: ALL -> String 
yALL all = show $ theA all 
-- record selector failed 

forall.hs:11:19: 
    Cannot use record selector `theA' as a function due to escaped type variables 
    Probable fix: use pattern-matching syntax instead 
    In the second argument of `($)', namely `theA all' 
    In the expression: show $ theA all 
    In an equation for `yALL': yALL all = show $ theA all 

अपने डेटा से कुछ अधिक से अधिक 5 तत्वों ले लो।

func1 (BigData _ _ _ _ elemx _ _) = func2 elemx 

वहाँ कि पोषणीय की तरह कोड बनाने के लिए या लपेट अप करने के लिए इतना है कि मैं चयनकर्ताओं किसी तरह का उपयोग कर सकते हैं एक अच्छा तरीका है: यह है कि अगर मैं पैटर्न मिलान का उपयोग कोड बनाए रखने के लिए मुश्किल है?

+3

संकेत: 'एए' का प्रकार क्या होगा? –

+0

@ लुइस वासरमैन: क्या आपका मतलब है yALL में मौजूदा वाक्यविन्यास का उपयोग करना? कैसे? – Nybble

+0

असल में, जवाब यह है कि यह एक स्पष्ट प्रकार नहीं है, इसलिए आपको एक व्यावहारिक प्रकार प्राप्त करने के लिए पैटर्न मिलान की आवश्यकता है। –

उत्तर

15

आप पैटर्न मिलान में रिकॉर्ड सिंटैक्स का उपयोग कर सकते हैं,

func1 BigData{ someField = elemx } = func2 elemx 

काम करता है और विशाल प्रकार के लिए बहुत कम टाइपिंग है।

+0

महान उत्तर! मैंने इसे बाद में पाया: डेटा बी {x :: Int, y :: Int}; मज़ा बी {..} = एक्स + वाई; यह एक विकल्प हो सकता है। – Nybble

16

मौजूदा प्रकार नियमित प्रकारों की तुलना में अधिक विस्तृत तरीके से काम करते हैं। जीएचसी (सही) आपको एक समारोह के रूप में theA का उपयोग करने से मना कर रहा है। लेकिन कल्पना करें कि ऐसी कोई प्रतिबंध नहीं थी। उस समारोह में किस प्रकार का होगा? forall बनाता GHC निर्माता के तर्क का प्रकार "भूल"

-- Not a real type signature! 
theA :: ALL -> t -- for a fresh type t on each use of theA; t is an instance of Show 

यह बहुत कुदरती तौर से कहें,;: यह कुछ इस तरह होना चाहिए था टाइप सिस्टम को पता है कि यह प्रकार Show का एक उदाहरण है। तो जब आप निर्माता के तर्क के मूल्य को निकालने का प्रयास करते हैं, तो मूल प्रकार को पुनर्प्राप्त करने का कोई तरीका नहीं है।

दृश्यों के पीछे क्या जीएचसी करता है, यह है कि उपरोक्त नकली प्रकार के हस्ताक्षर पर टिप्पणी क्या है- हर बार जब आप पैटर्न ALL कन्स्ट्रक्टर के खिलाफ मेल खाते हैं, तो कन्स्ट्रक्टर के मूल्य से जुड़ी चर को एक अद्वितीय प्रकार असाइन किया जाता है जो गारंटीकृत है हर दूसरे प्रकार से अलग। उदाहरण के लिए इस कोड डालें:

case ALL "foo" of 
    ALL x -> show x 

चर x एक अद्वितीय प्रकार है कि कार्यक्रम में हर दूसरे प्रकार से अलग है और किसी भी प्रकार के चर के साथ मिलान नहीं किया जा सकता हो जाता है। इन अद्वितीय प्रकारों को शीर्ष स्तर से बचने की अनुमति नहीं है- यही कारण है कि theA फ़ंक्शन के रूप में उपयोग नहीं किया जा सकता है।

+5

आम तौर पर, आप एक आश्रित प्रकार के रूप में एक आश्रित प्रकार के बारे में सोच सकते हैं, जहां पहला तत्व एक प्रकार ('*') है और दूसरा उस प्रकार का मान है - 'Σ [a: *] a'। समस्या यह है कि, जब आप ट्यूपल के दूसरे तत्व के प्रक्षेपण के लिए एक प्रकार के हस्ताक्षर लिखने का प्रयास करते हैं, तो आपको पहले तत्व के मान को जानने की आवश्यकता होती है। इसे हास्केल में व्यक्त नहीं किया जा सकता है। यदि आपके पास निर्भर रूप से टाइप की गई भाषा है तो आप इसे (एग्डा नोटेशन का उपयोग करके) लिख सकते हैं: '(x: Σ [a: *] a) → fst x'। – Vitus

+4

+1 यह त्रुटि संदेश बताता है "एक प्रकार के रूप में रिकॉर्ड चयनकर्ता 'ए' का उपयोग नहीं कर सकता ** बच निकले प्रकार चर के कारण **" –

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

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