हास्केल में बड़े कार्यक्रम लिखते समय, मुझे आमतौर पर एक समस्या में चल रहा है। मुझे लगता है कि मैं अक्सर कई अलग-अलग प्रकारों को चाहता हूं जो आंतरिक प्रतिनिधित्व और कई मूल संचालन साझा करते हैं।एक ही आंतरिक प्रतिनिधित्व और न्यूनतम बॉयलरप्लेट के साथ एकाधिक प्रकारों को संभालना?
इस समस्या को हल करने के लिए दो अपेक्षाकृत स्पष्ट दृष्टिकोण हैं।
कोई एक प्रकार का वर्ग और GeneralizedNewtypeDeriving
एक्सटेंशन का उपयोग कर रहा है। उपयोग केस इच्छाओं के साझा संचालन का समर्थन करने के लिए एक प्रकार के वर्ग में पर्याप्त तर्क रखें। वांछित प्रतिनिधित्व के साथ एक प्रकार बनाएँ, और उस प्रकार के लिए प्रकार वर्ग का एक उदाहरण बनाएँ। फिर, प्रत्येक उपयोग के मामले के लिए, नए प्रकार के साथ इसके लिए रैपर बनाएं, और सामान्य वर्ग प्राप्त करें।
दूसरा एक प्रकार का फैंटम प्रकार परिवर्तक के साथ घोषित करना है, और उसके बाद EmptyDataDecls
का उपयोग प्रत्येक अलग-अलग उपयोग केस के लिए अलग-अलग प्रकार बनाने के लिए करें।
मेरी मुख्य चिंता आंतरिक प्रतिनिधित्व और संचालन साझा करने वाले मानों को मिश्रित नहीं कर रही है, लेकिन मेरे कोड में अलग-अलग अर्थ हैं। उन दोनों दृष्टिकोणों ने उस समस्या को हल किया है, लेकिन काफी बेकार महसूस करते हैं। मेरी दूसरी चिंता बॉयलरप्लेट की मात्रा को कम कर रही है, और दोनों दृष्टिकोण उस पर पर्याप्त प्रदर्शन करते हैं।
प्रत्येक दृष्टिकोण के फायदे और नुकसान क्या हैं? क्या कोई ऐसी तकनीक है जो मैं चाहता हूं कि वह मुझे करने के करीब आती है, बॉयलरप्लेट कोड के बिना टाइप सुरक्षा प्रदान करती है?
यदि मेमोरी मुझे सेवा देती है, 'डेटा फू ए = फू ए', 'डेटा फू एबी = फू ए', और 'न्यूटाइप बार ए = बार (फू ए)' (पहले 'फू' के साथ) सभी को एक ही संकलित करना चाहिए रनटाइम प्रतिनिधित्व, इसलिए प्रदर्शन में एक गैर-मामूली अंतर खोजना कुछ हद तक अप्रत्याशित होगा। –
@camccann ghc-core और मानदंड की सुंदरता स्मृति पूरक के लिए अनुभवजन्य सबूत है! :) मुझे लगता है कि प्रदर्शन प्रश्न के साथ और अधिक करना है कि कक्षा से आने वाले संचालन मूल्य के रनटाइम प्रतिनिधित्व के विपरीत उनके प्रदर्शन को प्रभावित करते हैं या नहीं। पॉलिमॉर्फिक फ़ंक्शन '(सामान्य ए, सामान्य बी) => ए -> बी -> Int' से' सामान्य 2 ए -> सामान्य 2 बी -> Int' से जाते हैं। – Anthony