उस @n
आधुनिक हास्केल की एक उन्नत विशेषता है, जिसे आमतौर पर LYAH जैसे ट्यूटोरियल द्वारा कवर नहीं किया जाता है, और न ही रिपोर्ट पाया जा सकता है।
इसे एक प्रकार का एप्लिकेशन कहा जाता है और यह जीएचसी भाषा एक्सटेंशन है। इसे समझने के लिए, इस सरल बहुरूपी फ़ंक्शन पर विचार करें
dup :: forall a . a -> (a, a)
dup x = (x, x)
सहज dup
रूप से कॉलिंग कार्य इस प्रकार है:
- फोन करने वाले एक चुनता प्रकार
a
- फोन करने वाले एक चुनता मूल्य
x
पहले से चुना प्रकार कीa
dup
फिर प्रकार के मूल्य के साथ उत्तर देता है (a,a)
एक अर्थ में, dup
दो तर्क लेता है: प्रकार a
और मूल्य x :: a
। हालांकि, जीएचसी आमतौर पर टाइप करने में सक्षम होता है a
(उदाहरण के लिए x
, या उस संदर्भ से जहां हम उपयोग कर रहे हैं dup
), इसलिए हम आम तौर पर केवल एक तर्क पास करते dup
हैं x
। उदाहरण के लिए, हमारे पास है
dup True :: (Bool, Bool)
dup "hello" :: (String, String)
...
अब, क्या होगा अगर हम a
स्पष्ट रूप से पारित करना चाहते हैं ? ठीक है, उस स्थिति में हम TypeApplications
एक्सटेंशन को चालू कर सकते हैं , और लिख सकते हैं
dup @Bool True :: (Bool, Bool)
dup @String "hello" :: (String, String)
...
@...
प्रकारों को मानने वाले तर्कों पर ध्यान दें (मूल्यों पर नहीं)। वे कुछ हैं जो संकलित समय पर मौजूद हैं, केवल - रनटाइम पर तर्क मौजूद नहीं है।
हम ऐसा क्यों चाहते हैं? खैर, कभी-कभी कोई x
आस-पास नहीं होता है, और हम संकलक को सही चुनने के लिए उकसाना चाहते हैं a
। उदाहरण के लिए
dup @Bool :: Bool -> (Bool, Bool)
dup @String :: String -> (String, String)
...
टाइप एप्लिकेशन अक्सर कुछ अन्य एक्सटेंशन के साथ संयोजन में उपयोगी होते हैं जो GHC के लिए अस्पष्ट प्रकार या टाइप परिवारों की तरह अप्रभावी बनाते हैं। मैं उन पर चर्चा नहीं करूंगा, लेकिन आप बस यह समझ सकते हैं कि कभी-कभी आपको कंपाइलर की मदद करने की आवश्यकता होती है, खासकर जब शक्तिशाली टाइप-स्तरीय विशेषताओं का उपयोग करते हुए।
अब, अपने विशिष्ट मामले के बारे में। मेरे पास सभी विवरण नहीं हैं, मैं पुस्तकालय को नहीं जानता, लेकिन यह बहुत संभावना है कि आपका प्रकार स्तर परn
प्राकृतिक-संख्या मान का प्रतिनिधित्व करता है । यहां हम उपर्युक्त लोगों की तरह उन्नत एक्सटेंशन में गोताखोरी कर रहे हैं, प्लस DataKinds
, हो सकता है GADTs
, और कुछ टाइपकास्ट मशीनरी। जबकि मैं सब कुछ नहीं समझा सकता हूँ, उम्मीद है कि मैं कुछ बुनियादी जानकारी प्रदान कर सकता हूँ। intuitively,
foo :: forall n . some type using n
तर्क के रूप में @n
, एक तरह का संकलन-समय प्राकृतिक है, जो रनटाइम में पारित नहीं होता है। बजाय,
foo :: forall n . C n => some type using n
लेता है @n
एक साथ (संकलन समय), एक साथ सबूत है कि n
संतुष्ट रोके C n
। उत्तरार्द्ध एक रन-टाइम तर्क है, जो वास्तविक मूल्य को उजागर कर सकता है n
। वास्तव में, आपके मामले में, मुझे लगता है कि आपके पास बहुत कुछ जैसा है
value :: forall n . Reflects n Int => Int
जो अनिवार्य रूप से कोड को "-मान" के रूप में अनिवार्य रूप से "प्रकार" तक पहुंचने के लिए, शब्द-स्तर पर प्राकृतिक-प्रकार को लाने की अनुमति देता है। (उपरोक्त प्रकार को एक "अस्पष्ट" माना जाता है, वैसे - आपको वास्तव में आवश्यकता है@n
में अवज्ञा करने की है)।
अंत में: किसी n
को टाइप स्तर पर पास क्यों करना चाहिए यदि हम बाद में उसे टर्म स्तर में परिवर्तित करते हैं? केवल कार्यों को लिखना आसान नहीं होगा
foo :: Int -> ...
foo n ... = ... use n
अधिक बोझिल के बजाय
foo :: forall n . Reflects n Int => ...
foo ... = ... use (value @n)
ईमानदार जवाब है: हाँ, यह आसान होगा। हालांकि, n
प्रकार के स्तर पर होने से कंपाइलर अधिक स्थिर जांच करने की अनुमति देता है। उदाहरण के लिए, आप "पूर्णांक मोडुलो n
" का प्रतिनिधित्व करने के लिए एक प्रकार चाहते हैं , और उन्हें जोड़ने की अनुमति दे सकते हैं। बीत रहा है
data Mod = Mod Int -- Int modulo some n
foo :: Int -> Mod -> Mod -> Mod
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
काम करता है, लेकिन कोई जाँच नहीं है x
और y
एक ही मापांक के हैं। हम सेब और संतरे जोड़ सकते हैं, अगर हम सावधान नहीं हैं। हम इसके बजाय लिख सकते हैं
data Mod n = Mod Int -- Int modulo n
foo :: Int -> Mod n -> Mod n -> Mod n
foo n (Mod x) (Mod y) = Mod ((x+y) `mod` n)
जो बेहतर है, लेकिन foo 5 x y
फिर भी जब n
नहीं है तब भी कॉल करने की अनुमति देता है 5
। अच्छा नही। बजाय,
data Mod n = Mod Int -- Int modulo n
-- a lot of type machinery omitted here
foo :: forall n . SomeConstraint n => Mod n -> Mod n -> Mod n
foo (Mod x) (Mod y) = Mod ((x+y) `mod` (value @n))
चीजों को गलत होने से रोकता है। संकलक सांख्यिकीय रूप से सब कुछ जांचता है। कोड का उपयोग करना कठिन है, हां, लेकिन एक अर्थ में इसका उपयोग करना कठिन है, यह संपूर्ण बिंदु है: हम उपयोगकर्ता के लिए गलत मापांक के कुछ जोड़ने की कोशिश करना असंभव बनाना चाहते हैं।
समापन: ये बहुत ही उन्नत एक्सटेंशन हैं। यदि आप एक शुरुआत कर रहे हैं, तो आपको इन तकनीकों की दिशा में धीरे-धीरे प्रगति करने की आवश्यकता होगी। यदि आप केवल एक छोटे से अध्ययन के बाद उन्हें समझ नहीं पाते हैं, तो निराश न हों, इसमें कुछ समय लगता है। एक समय में एक छोटा सा कदम बनाएं, प्रत्येक सुविधा के बिंदु को समझने के लिए कुछ अभ्यासों को हल करें। और तुम हमेशा StackOverflow होगा जब आप फंस रहे हैं :-)