2012-01-25 12 views
6

में फ़ंक्शन ओवरलोडिंग कार्यान्वित करें मैं एक C++ प्रोग्राम के समान हास्केल कोड लिखने की समस्या पर काम कर रहा हूं।हास्केल

सी ++ कोड है:

class Rectangle 
{ 
    private: 
     int length; 
     int width; 
    public: 
     Rectangle() 
     { 
      length = 0; 
      width = 0; 
     } 
     Rectangle(int x) 
     { 
      length = x; 
      width =0; 
     } 
     Rectangle (int x , int y) 
     { 
      length = x; 
      width = y; 
     } 
}; 

समान हास्केल कोड लिखने के लिए मैं तो मैं एक लोड समारोह जो निर्माता के रूप में कार्य कर सकते हैं बनाने के बारे में सोचा एक डेटा प्रकार बनाया आयत

data Rectangle = Rectangle Length Width deriving (Eq, Show , Read) 
type Length = Int 
type Width = Int 

। लेकिन मुझे समझ में नहीं आता कि विभिन्न तर्कों के साथ फ़ंक्शन ओवरलोडिंग को कैसे कार्यान्वित किया जाए। कृपया मदद करें। धन्यवाद।

+1

मैं सी ++ के बाद हैकेल मॉडल करने की कोशिश करने से परेशान नहीं होगा; यह सिर्फ बहुत दर्द का कारण बन जाएगा। इसके अलावा, आपका दूसरा आयताकार कन्स्ट्रक्टर एक लाइन क्यों है? मुझे लगता है कि एक और समझदार कार्यान्वयन डिफ़ॉल्ट रूप से (1, 1) होगा, और यदि आप एक int प्राप्त करते हैं, तो एक वर्ग बनाने के लिए (x, x) में गुजरें। – alternative

+0

कभी कन्स्ट्रक्टर प्रारंभिक सूची के बारे में सुना है? –

+2

@VladLazarenko: कभी उन लोगों के बारे में सुना है जो अभी भी सीख रहे हैं? (संकेत: आप उनमें से हैं, हर कोई है) –

उत्तर

21

यह मुहावरेदार नहीं माना जाता है, और संभावना पर बाद में भ्रामक त्रुटियों को बढ़ावा मिलेगा:

अब आप कुछ Rectangle मान निर्धारित कर सकते हैं। इसके बजाय, आप बस कार्यों कि डेटा का निर्माण परिभाषित करना चाहिए:

point :: Rectangle 
point = Rectangle 0 0 

line :: Length -> Rectangle 
line l = Rectangle l 0 

square :: Int -> Rectangle 
square a = Rectangle a a 

यह आपको स्पष्ट ऐसे नाम हैं जो, प्रत्येक से अधिक भार के अर्थ विज्ञान का वर्णन नहीं बल्कि संख्या और तर्क का प्रकार आप जो को स्पष्ट करने के लिए दिया पर भरोसा करने की बजाय देने की अनुमति देता मतलब है।

हालांकि, अगर आप अतिभारित संस्करण लिखने के लिए चाहते हैं, आप इसे आसानी से typeclasses के साथ क्या कर सकते हैं:

class MakeRectangle a where 
    rectangle :: a 

instance MakeRectangle Rectangle where 
    rectangle = Rectangle 0 0 

instance MakeRectangle (Length -> Rectangle) where 
    rectangle l = Rectangle l 0 

instance MakeRectangle (Length -> Width -> Rectangle) where 
    rectangle = Rectangle 

आप इस संकलन के लिए अपनी फ़ाइल के शीर्ष पर {-# LANGUAGE FlexibleInstances #-} की आवश्यकता होगी। इस तरह की एक चाल मानक Text.Printf लाइब्रेरी द्वारा उपयोग की जाती है, लेकिन मैं इसे हास्केल में ओवरलोडिंग का विशेष रूप से अच्छा उदाहरण नहीं मानूंगा; ओवरलोडेड वैल्यू के प्रकार के लिए लगभग हमेशा कुछ संरचना होती है, जबकि यहां इसकी पूरी संरचना उदाहरण के आधार पर निर्धारित होती है, जो टाइप अनुमान के तरीके में मिल सकती है; इतना ही नहीं, लेकिन ऐसे कोई उचित कानून नहीं हैं जो उदाहरणों को नियंत्रित करते हैं (वास्तव में, किसी भी प्रकार की अनुमति देने के लिए प्रकार बहुत सामान्य है)।

लेकिन यदि आप वास्तव में ऐसा करना चाहते हैं, तो आप कर सकते हैं, और आमतौर पर यह एक बुरा विचार है, कभी-कभी (printf के मामले में) यह आपके इच्छित इंटरफ़ेस को पूरा करने का एकमात्र तरीका है।

GHCi में यह आज़माने के लिए, आप प्रकार आप स्पष्ट रूप से उपयोग कर रहे हैं का उल्लेख करना होगा, या यह उदाहरणों को हल करने में सक्षम नहीं होगा:

GHCi> rectangle :: Rectangle 
Rectangle 0 0 
GHCi> rectangle (1 :: Length) :: Rectangle 
Rectangle 1 0 
GHCi> rectangle (1 :: Length) (2 :: Width) :: Rectangle 
Rectangle 1 2 
+0

मैं प्रोग्राम को संकलित करने में सक्षम नहीं हूं। त्रुटि 'आयत के लिए एकाधिक घोषणाएं' –

+0

क्या आपने इंडेंटेशन को संरक्षित करना सुनिश्चित किया था? क्या आपके पास फ़ाइल में कहीं और 'आयताकार' की एक और घोषणा है? यदि यह उनमें से न तो है, तो उस पूर्ण फ़ाइल को जोड़ें जिसे आप अपने प्रश्न में संकलित कर रहे हैं और मैं एक नज़र डालेगा। – ehird

+1

आप मेरे कोड से रिक्त स्थान शामिल करना भूल गए हैं; हास्केल एक इंडेंटेशन-संवेदनशील भाषा है। – ehird

22

आप उस व्यवहार तक पहुंचने के लिए रिकॉर्ड सिंटैक्स का उपयोग कर सकते हैं।

data Rectangle = Rectangle {len :: Length, width :: Width} deriving (Eq, Show , Read) 
type Length = Int 
type Width = Int 

rectangle = Rectangle { len = 0, width = 0 } 

rectangle :: Rectangle यहां आपका कन्स्ट्रक्टर होगा। , हालांकि यह संभव है हास्केल में इस तरह के अधिक भार क्या करना

λ> let a = rectangle {len = 1} 

λ> a 
Rectangle {len = 1, width = 0} 
4

नहीं है कि तुम क्या कर रहे हैं बस यह देखने के लिए:

data Rectangle = Point | Line Int | Rectangle Int Int