मैं एक छोटे से लैम्ब्डा कैलकुलस कंपाइलर पर काम कर रहा हूं, जिसमें एक काम करने वाला हिंडले-मिलनर टाइप इंट्रेंस सिस्टम है और अब यह रिकर्सिव लेट्स (लिंक्ड कोड में नहीं) का भी समर्थन करता है, जो मुझे समझ में आता है कि इसे पूरा करने के लिए पर्याप्त होना चाहिए ।
अब समस्या यह है कि मुझे यह पता नहीं है कि इसे सूचियों का समर्थन कैसे करना है, या क्या यह पहले से ही उनका समर्थन करता है और मुझे उन्हें सांकेतिक शब्दों में बदलना चाहिए। मैं नए नियमों को टाइप सिस्टम में शामिल किए बिना उन्हें परिभाषित करने में सक्षम होना चाहता हूं।
सबसे आसान तरीका जो मैं सोच सकता हूँ कि एक सूची x
कुछ ऐसी है जो या तो null
(या खाली सूची) है, या एक जोड़ी जिसमें एक x
और दोनों की सूची है x
। लेकिन ऐसा करने के लिए मुझे जोड़े और / या परिभाषित करने में सक्षम होना चाहिए, जो मेरा मानना है कि उत्पाद और योग प्रकार हैं।
लगता है कि मैं इस तरह से जोड़े परिभाषित कर सकता हूं:
pair = λabf.fab
first = λp.p(λab.a)
second = λp.p(λab.b)
चूंकि pair
प्रकार होता है a -> (b -> ((a -> (b -> x)) -> x))
, पास करने के बाद, कहते हैं, एक int
और एक string
है, यह प्रकार के साथ कुछ उपज होता (int -> (string -> x)) -> x
है, जो की एक जोड़ी का प्रतिनिधित्व किया जाएगा int
और string
। मुझे यहाँ क्या परेशान करता है कि अगर यह एक जोड़ी का प्रतिनिधित्व करता है, तो यह तार्किक रूप से समान क्यों नहीं है और न ही प्रस्ताव का तात्पर्य है int and string
। हालांकि, इसके बराबर है (((int and string) -> x) -> x)
, जैसे कि मैं केवल उत्पाद प्रकार के मापदंडों के रूप में कार्य कर सकता हूं। यह उत्तरइस समस्या को हल करने के लिए लगता है, लेकिन मुझे नहीं पता कि प्रतीकों का वह क्या उपयोग करता है। इसके अलावा, अगर यह वास्तव में एक उत्पाद प्रकार को एनकोड नहीं करता है, तो क्या मैं कुछ उत्पाद प्रकारों के साथ कर सकता हूं जो मैं ऊपर जोड़े की मेरी परिभाषा के साथ नहीं कर सकता था (मैं भी उसी तरह n-tuples को परिभाषित कर सकता हूं)? यदि नहीं, तो क्या यह इस तथ्य का खंडन नहीं करेगा कि आप (एएफएआईके) संयोजन को केवल निहितार्थ का उपयोग करके व्यक्त नहीं कर सकते हैं?
इसके अलावा, योग प्रकार के बारे में कैसे? क्या मैं किसी प्रकार केवल फ़ंक्शन प्रकार का उपयोग करके इसे एनकोड कर सकता हूं? यदि हां, तो क्या यह सूचियों को परिभाषित करने के लिए पर्याप्त होगा? या फिर, क्या मेरे प्रकार प्रणाली का विस्तार किए बिना सूचियों को परिभाषित करने का कोई अन्य तरीका है? और यदि नहीं, तो मुझे क्या बदलाव करने की आवश्यकता होगी यदि मैं इसे यथासंभव सरल रखना चाहता हूं?
कृपया ध्यान रखें कि मैं एक कंप्यूटर प्रोग्रामर हूं, लेकिन कंप्यूटर साइंटिस्ट नहीं हूं और न ही गणितज्ञ और गणित पढ़ने में बहुत खराब हूं।
संपादित करें: मुझे यकीन नहीं है कि मैंने अब तक जो भी लागू किया है उसका तकनीकी नाम क्या है, लेकिन मेरे पास मूल रूप से कोड है जो मैंने ऊपर लिंक किया है, जो एक बाधा पीढ़ी एल्गोरिथ्म है जो अनुप्रयोगों, अमूर्त और चर के लिए नियमों का उपयोग करता है। हिंले-मिलनर एल्गोरिथ्म और फिर एक एकीकरण एल्गोरिथ्म से जो प्रमुख प्रकार प्राप्त करता है। उदाहरण के लिए, अभिव्यक्ति \a.a
प्रकार का उत्पादन करेगी a -> a
, और अभिव्यक्ति में \a.(a a)
चेक त्रुटि होगी। इसके शीर्ष पर, वास्तव में एक let
नियम नहीं है, लेकिन एक ऐसा फ़ंक्शन है जिसका एक ही प्रभाव है जो आपको इस छद्म कोड जैसे पुनरावर्ती वैश्विक कार्यों को परिभाषित करने देता है:
GetTypeOfGlobalFunction(term, globalScope, nameOfFunction)
{
// Here 'globalScope' contains a list of name-value pair where every value is of class 'ClosedType',
// meaning their type will be cloned before unified in the unification algorithm so that they can be used polymorphically
tempType = new TypeVariable() // Assign a dummy type to `tempType`, say, type 'x'.
// The next line creates an scope with everything in 'globalScope' plus the 'nameOfFunction = tempType' name-value pair
tempScope = new Scope(globalScope, nameOfFunction, tempType)
type = TypeOfTerm(term, tempScope) // Calculate the type of the term
Unify(tempType, type)
return type
// After returning, the code outside will create a 'ClosedType' using the returned type and add it to the global scope.
}
कोड मूल रूप से हमेशा की तरह शब्द का प्रकार प्राप्त करता है, लेकिन एकीकरण करने से पहले, यह फ़ंक्शन का नाम एक डमी प्रकार के साथ परिभाषित किया जा रहा है ताकि इसे स्कोप के रूप में इस्तेमाल किया जा सके।
संपादित करें 2: मुझे बस एहसास हुआ कि मुझे पुनरावर्ती प्रकारों की भी आवश्यकता होगी, जो मेरे पास नहीं है, जैसे मुझे चाहिए कि एक सूची को परिभाषित करने के लिए।
let func = \x -> (func x)
) आपको वही मिलता है जो मेरे पास है।