2017-07-31 8 views
6

मैंतरह हस्ताक्षर और परिवारों टाइप

type family Rep a 

और

type family Rep :: * -> * 

उम्मीद में ही हो, लेकिन ऐसा लगता है कि वहाँ एक अंतर

type family Rep a 
type instance Rep Int = Char 
-- ok 

type family Rep :: * -> * 
type instance Rep Int = Char 
-- Expected kind * -> *, but got 'Int' instead 

मैं बस एक से अधिक ठोकर खाई है है हास्केल एक्सटेंशन बग, या इस व्यवहार के लिए कुछ बिंदु है?

+6

बिंदु यह है कि परिवार 'टाइप-स्तरीय फ़ंक्शंस' नहीं हैं। वे 'प्रकार के परिवार' हैं। आपको मूल्य-स्तर पैटर्न मिलान के बीच सिंटैक्टिक समानताएं देखना चाहिए और संयोग के रूप में पारिवारिक उदाहरण घोषणाओं को टाइप करना चाहिए - दोनों में पूरी तरह से अलग अर्थशास्त्र हैं (उदाहरण के लिए मूल्य-स्तर फ़ंक्शन लिखने का प्रयास करें जो कि कन्स्ट्रक्टर 'वाम :: ए -> या तो अब ')। आप पहले से ही अंतर का एक न्यूनतम उदाहरण देखा है। दूसरा प्रकार का परिवार मूल रूप से केवल एक प्रकार का पर्याय है, क्योंकि इसमें केवल एक ही उदाहरण हो सकता है। पहला एक उचित प्रकार का परिवार है। – user2407038

+0

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

उत्तर

12

हां, एक सूक्ष्म अंतर है।

मोटे तौर पर, type family F a :: *->* राज्यों, कहते हैं, F Int[], Maybe की तरह एक injective प्रकार निर्माता है। इस संकलक, जो निम्न लिखें कोड की जांच कर सकते द्वारा शोषण किया जाता है:

type family F a :: * -> * 

-- these three examples can be removed/changed, if wished 
type instance F Int = [] 
type instance F Char = Maybe 
type instance F Bool = (,) String 

foo :: (F Int a :~: F Int b) -> (a :~: b) 
foo Refl = Refl 

लिखने के लिए ऊपर जाँच, संकलक तथ्य यह है कि F Int a ~ F Int b तात्पर्य a ~ b, जो injectivity से इस प्रकार का शोषण किया।

इसके बजाय, type family F a b :: * घोषित करने से F Int की इंजेक्शनिटी सुनिश्चित नहीं होती है, क्योंकि निम्नलिखित कानूनी हो जाते हैं।

type family F a b :: * 
type instance F Int a =() 
संबंधित मुद्दे