2011-12-26 17 views
5

जब मैं एक सीमित राज्य मशीन लिखने का प्रयास कर रहा था तो मैं हास्केल में "अनंत प्रकार" में आया हूं। मैंने सोचा था कि निम्नलिखित बहुत सहज ज्ञान युक्त था:हास्केल अनंत प्रकार और मेरा एफएसएम फ़ंक्शन

fsm []  _  acc = Right acc 
fsm (x:xs) state acc = 
    case state acc x of 
     Left err  -> Left err 
     Right (s, a) -> fsm xs s a 

मैं राज्य समारोह वर्तमान स्थिति (संचायक) और नई घटना देते हैं, और राज्य समारोह नई संचायक के साथ अगले राज्य समारोह पैदा करता है। मैं तब तक रिकर्स करता हूं जब तक मेरे पास कोई और घटना न हो।

संकलक मुझसे कहता है:

Occurs check: cannot construct the infinite type: 
    t1 = b0 -> t0 -> Either a0 (t1, b0) 
In the second argument of `fsm', namely `s' 

क्योंकि state अब एक अनंत प्रकार है। इसे काम करने के लिए मैं इसे पुनर्व्यवस्थित कैसे करूं?

उत्तर

8

इस प्रकार के प्रकार के साथ इस प्रकार के विनाश की तरह असीमित प्रकार; वे इसे असुरक्षित नहीं बनाते हैं, लेकिन वे प्रोग्रामों का एक बड़ा हिस्सा चुनते हैं जिन्हें आप वास्तव में नहीं करना चाहते हैं, इस प्रकार त्रुटियों को छुपाते हैं, और मेरा मानना ​​है कि वे टाइप अनुमान को भी कठिन बनाते हैं।

शुक्र है, समाधान सरल है: आपको बस newtype रैपर बनाने की आवश्यकता है। data और newtype घोषणाओं को निश्चित रूप से रिकर्सिव होने की अनुमति है (अन्यथा, हम सूचियां भी परिभाषित नहीं कर सके!); यह सिर्फ सादे, अनचाहे प्रकार हैं जो नहीं हैं।

newtype FSMState err acc ev = 
    FSMState { stepFSM :: acc -> ev -> Either err (FSMState err acc ev, acc) } 

fsm :: [ev] -> FSMState err acc ev -> acc -> Either err acc 
fsm []  _  acc = Right acc 
fsm (x:xs) state acc = 
    case stepFSM state acc x of 
     Left err  -> Left err 
     Right (s, a) -> fsm xs s a 
+0

धन्यवाद। मेरे लिए, यह सब अनंत प्रकार का नाम देता है, लेकिन टाइप स्वयं ही आत्म-संदर्भ है। कंपाइलर ने भी अनंत प्रकार को उसी तरह नाम दिया। मैंने सोचा होगा कि संकलक इसे नाम देकर इसे स्वचालित करने में सक्षम होगा। क्या मैं गलत हूँ? – Ana

+5

@ एना: हालांकि यह सच है कि हास्केल केवल आपके विकल्प को * पसंद * द्वारा अमान्य मानता है और आवश्यकता नहीं है, यह बहुत अच्छे कारण के लिए है; मेरे पास अभी कोई लिंक नहीं है, लेकिन * कई * सामान्य त्रुटियां जिन्हें हम जांचने के लिए टाइप सिस्टम पर भरोसा करते हैं - जैसे किसी तर्क को याद करना या फ़ंक्शन नाम लिखना दो बार - वैध रूप से टाइप किए गए (लेकिन टूटे हुए) प्रोग्राम बनें यदि आप अनंत अनुमति देते हैं प्रकार के। – ehird

+3

ध्यान दें कि यह प्रकार को नाम देने के समान सरल नहीं है: 'प्रकार अनंत = (बूल, अनंत)' भी प्रतिबंधित है; आपको इसे * डेटा प्रकार * में लपेटना होगा, जो त्रुटियों के लिए सभी संभावनाओं को दूर करता है, क्योंकि आपको स्पष्ट रूप से निर्माण और पैटर्न-मिलान (या एक्सेसर फ़ंक्शंस का उपयोग करना) है। – ehird

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