2017-07-16 6 views
8

कोडअनुमति दें विशिष्ट प्रकार और इस "अंतिम" उदाहरण में इसकी आवश्यकता क्यों है?

{-# LANGUAGE ScopedTypeVariables, TypeApplications #-} 

-- I know this particular example is silly. 
-- But that's not the point here. 
g :: forall a . RealFloat a => Bool 
g = True 

main :: IO() 
main = print (g @Double) 

त्रुटि

• Could not deduce (RealFloat a0) 
     from the context: RealFloat a 
     bound by the type signature for: 
        g :: RealFloat a => Bool 
     at app/Main.hs:3:6-35 
     The type variable ‘a0’ is ambiguous 
    • In the ambiguity check for ‘g’ 
     To defer the ambiguity check to use sites, enable AllowAmbiguousTypes 
     In the type signature: 
     g :: forall a. RealFloat a => Bool 

साथ GHC 8.0 पर संकलित करने के लिए तो AllowAmbiguousTypes जोड़ने कोड संकलन कर देगा विफल रहता है।

यहाँ मेरी प्रश्न हैं:

  • वास्तव में क्या AllowAmbiguousTypes है?
  • इस विशेष कोड को काम करने के लिए इसकी आवश्यकता क्यों है?
  • मुझे डर है कि AllowAmbiguousTypes जोड़ना मुझे इस विशेष कोड में वास्तव में चाहते हैं। यह डरावना लगता है। ऐसा लगता है जैसे यह हास्केल की टाइप सिस्टम को कम सुरक्षित बनाएगा, शायद अन्य क्षेत्रों में जिनके पास इस विशेष कोड से कोई लेना देना नहीं है। क्या ये भय निराधार हैं?
  • क्या कोई विकल्प हैं? इस मामले में, ऐसा लगता है जैसे हास्केल a0 टाइप वैरिएबल डालने वाला है जिसे मैंने कभी नहीं पूछा था। क्या इन असाधारण प्रकार चर बनाने के लिए हास्केल को बताने के लिए कोई विस्तार नहीं है - और केवल उन लोगों का उपयोग करें जिन्हें मैंने स्पष्ट रूप से अपने स्वयं के स्पष्ट forall a के साथ जोड़ने के लिए कहा था?
  • user2407038 की टिप्पणी के कारण एक प्रश्न जोड़ा गया: क्या आप कहेंगे कि AllowAmbiguousTypes एक गलत नाम है? क्या इसे बेहतर AllowUnusedTypeVariables के रूप में नामित किया गया होगा?
+7

एक संदिग्ध प्रकार वह है जिसमें उसके संदर्भ में एक प्रकार परिवर्तनीय होता है जिसका उल्लेख शरीर में नहीं किया गया है (कि '=> '' के दाईं ओर)। तो 'RealFloat a => ..' अस्पष्ट है जब '..' का उल्लेख नहीं है। अस्पष्ट प्रकार आम तौर पर एक प्रोग्रामर त्रुटि होते हैं, और टाइपएप्लिकेशंस से पहले वे पूरी तरह से बेकार थे, इसलिए आपको उन्हें अनुमति देने के लिए एक एक्सटेंशन की आवश्यकता है। पिछले दो प्रश्नों के लिए: यह किसी भी तरह से टाइपशेकर 'असुरक्षित' नहीं बनाता है; और आपका विकल्प 'RealFloat a => प्रॉक्सी ए -> बूल' लिखना है, जहां [प्रॉक्सी] (https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Proxy.html) है यहाँ। – user2407038

+3

एक विकल्प के रूप में, आप 'RealFloat a => टैग की गई एक बूल' का उपयोग कर सकते हैं, जहां 'टैग की गई' 'टैग की गई 'पैकेज से आती है, जो कुछ परिस्थितियों में प्रॉक्सी तरीके से अधिक कुशल हो सकती है। – dfeuer

+3

'मेरी आंखों में अनुमति दें', हानिरहित है। कई लैम्ब्डा कैलकुली में, प्रकार हमेशा स्पष्ट रूप से पारित होते हैं (उदा। 'मानचित्र @ ए @ बी एफ एक्सएस')। सादा हास्केल में, प्रकार अनुमानित होते हैं - जिसका मतलब है कि हमें उन्हें (अच्छा) पास नहीं करना है, और अगर हम चाहते हैं कि हम उन्हें भी पास नहीं कर सकते हैं। इसके कारण, टाइमर वाले प्रकार जिन्हें तर्क के प्रकार से अनुमानित नहीं किया जा सकता है या वापसी मूल्य प्रतिबंधित होना चाहिए। इसलिए हमें अव्यवस्था को जोड़ने के लिए केवल उन्हें छेड़छाड़ करने के लिए प्रॉक्सी/टैग का उपयोग करना होगा। हालांकि, अब जीएचसी स्पष्ट प्रकार के अनुप्रयोगों की अनुमति देता है, इसलिए हमें अब ऐसा नहीं करना है। – chi

उत्तर

9

AllowAmbiguousTypes क्या है?

latest GHC docs से, "एक प्रकार ty अस्पष्ट है यदि और केवल यदि ((undefined :: ty) :: ty) typecheck करने में विफल रहते हैं"। एक्सटेंशन AllowAmbiguousTypes बस इस चेक को अक्षम करता है - यह बीमार टाइप किए गए प्रोग्रामों को अनुमति नहीं देगा।

इस विशेष कोड को काम करने के लिए इसकी आवश्यकता क्यों है?

आदेश RealFloat a संतुष्ट है कि जब भी g प्रयोग किया जाता है की जाँच करने के लिए, GHC को पता है कि a है की जरूरत है। जीएचसी को बताने के लिए आपके पास रास्ता नहीं है (वेनिला हास्केल) aag के प्रकार में कहीं और नहीं होना चाहिए। एनोटेशन की कोई भी राशि आपको अस्पष्ट प्रकार परिवर्तनीय त्रुटि प्राप्त किए बिना g का उपयोग करने देगी।

हालांकि, अगर आप कहीं भी नहीं उपयोगg करते हैं, आप अभी भी अपने कोड AllowAmbiguousTypes को चालू करके संकलित करने के लिए मिल सकता है।

मुझे डर है कि AllowAmbiguousTypes जोड़कर मुझे इस विशेष कोड में वास्तव में और अधिक चाहिए। यह डरावना लगता है। ऐसा लगता है जैसे यह हास्केल की टाइप सिस्टम को कम सुरक्षित बनाएगा, शायद अन्य क्षेत्रों में जिनके पास इस विशेष कोड से कोई लेना देना नहीं है। क्या ये भय निराधार हैं?

हाँ वे हैं: अस्पष्टता की जांच आप परिभाषाएँ जो (वेनिला हास्केल, जो TypeApplications नहीं है में) एक अस्पष्ट प्रकार चर त्रुटि में परिणाम के बिना नहीं किया जा सकता है को पकड़ने की सुविधा देता है। इस चेक को अक्षम करने का मतलब है कि जब आप अपनी परिभाषा साइट के बजाय अभिव्यक्ति (या फ़ंक्शन) का उपयोग करते हैं तो आप संदिग्ध प्रकार परिवर्तनीय संदेश देखेंगे।

क्या कोई विकल्प हैं? इस मामले में, ऐसा लगता है जैसे हास्केल a0 टाइप वैरिएबल डालने वाला है जिसे मैंने कभी नहीं पूछा था। क्या इन असाधारण प्रकार चर बनाने के लिए हास्केल को बताने के लिए कोई विस्तार नहीं है - और केवल उन लोगों का उपयोग करें जिन्हें मैंने स्पष्ट रूप से अपने स्वयं के स्पष्ट forall a के साथ जोड़ने के लिए कहा था?

a0 इस उत्तर की शुरुआत में वर्णित अस्पष्टता जांच से आ रहा है। जीएचसी सिर्फ यह सुनिश्चित करने के लिए a0 नाम का उपयोग करता है कि यह a से अलग है। अस्पष्टता की जांच मूल रूप से सिर्फ typecheck को

((undefined :: forall a. RealFloat a => Bool) :: forall a0. RealFloat a0 => Bool) 

AllowAmbiguousTypes इस चेक को हटा कोशिश करता है। मुझे नहीं लगता कि एक ऐसा एक्सटेंशन है जो स्पष्ट forall एस के साथ केवल प्रकार हस्ताक्षरों पर अस्पष्टता जांच अक्षम करता है (हालांकि यह साफ और उपयोगी हो सकता है!)।

क्या आप कहेंगे कि AllowAmbiguousTypes एक गलत नाम है? क्या इसे बेहतर AllowUnusedTypeVariables के रूप में नामित किया गया होगा?

नामकरण चीजें कठिन हैं। :)

वर्तमान नाम एक्सटेंशन के बिना आपको प्राप्त त्रुटियों के प्रकार का संदर्भ देता है, इसलिए यह एक बुरा नाम नहीं है। मुझे लगता है कि यह राय का विषय है।


पहले TypeApplications (जो GHC 8.0 से एक अपेक्षाकृत नया विस्तार है) से (लोगों को भी इच्छा MonadFlatMapAble की तरह कुछ बुलाया गया था। बहुत सारे), वहाँ वास्तव में भाव कि चालू होने का उपयोग करने का कोई रास्ता नहीं था एक अस्पष्ट प्रकार परिवर्तनीय त्रुटि प्राप्त किए बिना अस्पष्टता जांच, इसलिए AllowAmbiguousTypes बहुत कम उपयोगी था।

+0

'क्योंकि जी के प्रकार में कहीं और नहीं होता है ← ← न केवल प्रकार में, बल्कि शरीर में भी नहीं होता है। यदि आप फ़ंक्शन के बॉडी में 'ए' वैरिएबल का उपयोग करते हैं तो आपको' -XAllowAmbiguousTypes' की आवश्यकता नहीं है। – Shersh

+0

@ शेरश आपके मन में क्या है? यदि आप फ़ंक्शन के बॉडी में टाइप वैरिएबल का उपयोग करते हैं (संभवतः 'स्कोप्ड टाइप टाइपरीबल्स' सक्षम के साथ) आप कॉलर पर टाइप नहीं करते हैं, तो कॉलर पर 'ए' होना चाहिए ... – Alec

+0

क्षमा करें। किसी भी तरह से मैं गलत हूँ। जब मैंने पिछले साल इस स्लाइड से कोड का परीक्षण किया तो ghc 8.0.1 के साथ यह काम किया। लेकिन अब यह '-XAllowAmbiguousTypes' के बिना काम नहीं करता है: http://slides.com/fp-ctd/lecture-15#/17 :( – Shersh

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