2010-06-19 4 views
16

चूंकि प्रकार चर पॉली-प्रकार नहीं रख सकते हैं, ऐसा लगता है कि रैंक * प्रकार के साथ हम अपने मोनोटाइप प्रतिबंध के कारण मौजूदा कार्यों का पुन: उपयोग नहीं कर सकते हैं।रैंक 2 प्रकार/रैंकेंटाइप पॉलीटाइप चर के बिना व्यावहारिक हैं?

उदाहरण के लिए, हम फ़ंक्शन (।) का उपयोग नहीं कर सकते हैं जब इंटरमीडिएट प्रकार एक पॉलीटाइप है। हमें जगह पर (।) फिर से लागू करने के लिए मजबूर किया जाता है। यह निश्चित रूप से (।) के लिए मामूली है लेकिन कोड के अधिक महत्वपूर्ण निकायों के लिए एक समस्या है।

मुझे लगता है कि ((एफ। जी) एक्स) (एफ (जी एक्स) के बराबर नहीं है) संदर्भित पारदर्शिता और इसके लाभों के लिए एक गंभीर झटका है।

ऐसा लगता है कि मुझे एक शो-स्टॉपर समस्या है, और ऐसा लगता है कि रैंक * प्रकार एक्सटेंशन व्यापक प्रसार के लिए लगभग अव्यवहारिक है।

क्या मुझे कुछ याद आ रही है? क्या रैंक * प्रकार को बाकी प्रकार के सिस्टम के साथ बेहतर तरीके से बातचीत करने की कोई योजना है?

संपादित करें: आप कैसे प्रकार (रनस्ट हमेशा के लिए) काम कर सकते हैं?

उत्तर

11

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

"बॉक्सी प्रकार" काम का मूल विचार टाइप एनोटेशन को यथासंभव प्रचारित करना है। टाइप चेकर प्रकार की जांच और टाइप अनुमान मोड के बीच स्विच करता है और उम्मीद है कि कोई और एनोटेशन की आवश्यकता नहीं है। यहां नकारात्मकता यह है कि एक प्रकार की एनोटेशन की आवश्यकता है या नहीं, यह समझाना मुश्किल है क्योंकि यह कार्यान्वयन के विवरण पर निर्भर करता है।

रेमी का एमएलएफ सिस्टम अब तक का सबसे अच्छा प्रस्ताव है; इसे कम से कम प्रकार की एनोटेशन की आवश्यकता होती है और कई कोड ट्रांसफॉर्मेशन के तहत स्थिर होती है। समस्या यह है कि यह प्रकार प्रणाली को बढ़ाता है। निम्न मानक उदाहरण इस दिखाता है:

choose :: forall a. a -> a -> a 
id :: forall b. b -> b 

choose id :: forall c. (c -> c) -> (c -> c) 
choose id :: (forall c. c -> c) -> (forall c. c -> c) 

उपरोक्त दोनों प्रकार के सिस्टम एफ में admissable पहले एक मानक Hindley/मिलनर प्रकार है और प्रेडीकेटिव इन्स्टेन्शियशन का उपयोग करता है, दूसरा एक impredicative इन्स्टेन्शियशन उपयोग करता है। न तो प्रकार दूसरे की तुलना में अधिक सामान्य है, इसलिए अनुमान लगाएं कि उपयोगकर्ता किस प्रकार का चाहता है, और यह आमतौर पर एक बुरा विचार है।

एमएलएफ इसके बजाय सिस्टम एफ को बाध्य मात्रा के साथ बढ़ाता है।प्रिंसिपल (= सबसे सामान्य) ऊपर के उदाहरण के लिए टाइप होगा:

choose id :: forall (a < forall b. b -> b). a -> a 

आप के रूप में इस पढ़ें "choose id टाइप है aa जहां aforall b. b -> b का एक उदाहरण होना चाहिए करने के लिए" कर सकते हैं।

दिलचस्प बात यह है कि यह अकेले मानक हिंडली/मिलनर से अधिक शक्तिशाली नहीं है। एमएलएफ इसलिए कठोर मात्रा को भी अनुमति देता है। निम्नलिखित दो प्रकार के बराबर हैं:

(forall b. b -> b) -> (forall b. b -> b) 
forall (a = forall b. b -> b). a -> a 

कठोर मात्रा प्रकार एनोटेशन और तकनीकी जानकारी से शुरू की है वास्तव में बहुत जटिल हैं। उलझन यह है कि एमएलएफ को केवल बहुत कम प्रकार की टिप्पणियों की आवश्यकता होती है और जब उनकी आवश्यकता होती है तो उनके लिए एक सरल नियम होता है। कमियां हैं:

  • प्रकार, पढ़ने के लिए कठिन हो सकता है, क्योंकि '<' के दाहिने हाथ की ओर आगे नेस्टेड quantifications हो सकते हैं।

  • हाल ही में एमएलएफ के स्पष्ट रूप से टाइप किए गए संस्करण मौजूद नहीं थे। टाइप किए गए कंपाइलर ट्रांसफॉर्मेशन के लिए यह महत्वपूर्ण है (जैसे जीएचसी करता है)। Boris Yakobowski's PhD thesis का भाग 3 इस तरह के संस्करण पर पहला प्रयास है। (भाग 1 & 2 भी दिलचस्प हैं, वे "ग्राफिकल प्रकार" के माध्यम से MLF की एक अधिक सहज प्रतिनिधित्व का वर्णन।)

FPH करने के लिए वापस आ रहा है, इसके मूल विचार आंतरिक रूप से MLF तकनीक का उपयोग करने के लिए है, लेकिन प्रकार की आवश्यकता होती है let बाइंडिंग पर एनोटेशन। यदि आप केवल हिंडली/मिलनर प्रकार चाहते हैं, तो कोई टिप्पणी आवश्यक नहीं है। यदि आप उच्च-रैंक प्रकार चाहते हैं, तो आपको अनुरोधित प्रकार निर्दिष्ट करना होगा, लेकिन केवल let (या शीर्ष-स्तर) बाध्यकारी पर।

एफपीएच (एमएलएफ की तरह) अप्रासंगिक क्षणिकता का समर्थन करता है, इसलिए मुझे नहीं लगता कि आपकी समस्या लागू होती है। इसलिए इसे ऊपर f . g अभिव्यक्ति टाइप करने में कोई समस्या नहीं होनी चाहिए। हालांकि, एफएचएच अभी तक जीएचसी में लागू नहीं किया गया है और अधिकतर संभावना नहीं होगी। कठिनाइयों समानता दबाव (और संभवतः वर्ग की बाधाओं के प्रकार) के साथ बातचीत से आती हैं। मुझे यकीन नहीं है कि नवीनतम स्थिति क्या है, लेकिन मैंने सुना है कि एसपीजे अपर्याप्तता से दूर जाना चाहता है। वह सभी अभिव्यक्तिपूर्ण शक्ति लागत पर आती है, और अब तक कोई किफायती और समस्त समाधान नहीं मिला है।

7

क्या रैंक * प्रकार शेष प्रकार के सिस्टम के साथ बेहतर बातचीत करने की कोई योजना है?

यह देखते हुए कि एसटी मोनैड कितना आम है, कम से कम रैंक 2 प्रकार विपरीत हैं, इसके विपरीत सबूत हैं। हालांकि, आप "सेक्सी/बॉक्सी प्रकार" श्रृंखलाओं की श्रृंखला देख सकते हैं, मनमानी रैंक पॉलिमॉर्फिज्म दूसरों के साथ बेहतर कैसे खेलता है।

FPH : First-class Polymorphism for Haskell, डिमिट्रायस Vytiniotis, स्टेफ़नी Weirich, और साइमन Peyton जोन्स, ICFP लिए 2008.

भी देखें -XImpredicativeTypes प्रस्तुत - जो दिलचस्प है, समाप्त होने वाली है!

+0

आप कैसे प्रकार (रनस्ट हमेशा के लिए) काम कर सकते हैं? – Peaker

6

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

Maybe :: * -> * 
(forall a. a -> a) :: * 

हालांकि, यह एक झूठ है। यह एक अपरिवर्तनीय प्रणाली में सच है, और इस तरह के एक सिस्टम में, आप लिख सकते हैं:

Maybe (forall a. a -> a) :: * 

और यह ठीक काम करेगा। यही वह है जो ImpredicativeTypes सक्षम करता है। विस्तार के बिना, इस बारे में सोचने की उचित तरीका है:

Maybe :: *m -> *m 
(forall a :: *m. a -> a) :: *p 

और इस तरह वहाँ एक प्रकार बेमेल है जब आप ऊपर आवेदन फार्म का प्रयास करें।

जीएचसी अपर्याप्तता के मोर्चे पर काफी असंगत है, हालांकि।उदाहरण के लिए, प्रकार id के लिए मैं ऊपर दिया होगा:

id :: (forall a :: *m. a -> a) 

लेकिन GHC ख़ुशी से एनोटेशन स्वीकार करेंगे (RankNTypes के साथ सक्षम है, लेकिन नहीं ImpredicativeTypes):

id :: (forall a. a -> a) -> (forall a. a -> a) 

भी forall a. a -> a हालांकि एक नहीं है मोनोटाइप। इसलिए, यह मात्राबद्ध चर के अपरिवर्तनीय तत्कालता की अनुमति देगा जो केवल (->) के साथ उपयोग किया जाता है यदि आप इस तरह एनोटेट करते हैं। लेकिन यह मुझे ऐसा नहीं करेगा, मुझे लगता है, जो runST $ ... समस्याओं का कारण बनता है। इसका उपयोग विज्ञापन-मुक्त तत्कालता नियम (जिन विवरणों के बारे में मैं विशेष रूप से स्पष्ट नहीं था) के साथ हल किया जाता था, लेकिन यह नियम जोड़ा जाने के कुछ समय बाद हटा दिया गया था।