2013-05-08 10 views
7

मैं निम्नलिखित typeclass उपयोग कर रहा हूँ:हास्केल को दो मॉड्यूल से एक ही उदाहरण आयात करने के लिए कैसे बताना है?

module T where 
class T a where 
    v :: a 

T Int का एक उदाहरण है कि मैं कार्यान्वित:

import T 
import A (av) 

instance T Int where 
    v = 0 

main = putStrLn (av ++ show v) 

और एक मॉड्यूल है कि मैं जो भी का एक उदाहरण है से एक मूल्य, उपयोग करना चाहते हैं T Int

module A where 
import T 
instance T Int where 
    v = 0 
av = "value from A" 

समस्या यह काम नहीं करता है:

$ runghc Main.hs 

Main.hs:4:9: 
    Duplicate instance declarations: 
     instance T Int -- Defined at Main.hs:4:9-13 
     instance T Int -- Defined at A.hs:3:9-13 

हास्केल शिकायत एक ही उदाहरण के लिए 2 घोषणाओं देखते हैं कि। मैं उसे कैसे बता सकता हूं कि B से उदाहरण आयात करने के लिए, या दोनों उदाहरणों को एकजुट करने के लिए, या केवल Main से उदाहरण का उपयोग करने के लिए?

+1

ऐसा मत करो। उचित समाधान केवल एक ही स्थान पर उदाहरण घोषित करना है। – hammar

+0

@hammar: मैंने 'टी' या' बी' नहीं लिखा था, लेकिन मैं 'बी' से एक मान का उपयोग करना चाहता हूं, और मैं' टी' का उदाहरण बनाना चाहता हूं। – Dog

+1

आह, यह इसे कठिन बना देता है। उस स्थिति में, आप मौजूदा प्रकार को लपेटने के लिए 'न्यूटाइप' बना सकते हैं और इसके बजाय 'newtype' के लिए अपना उदाहरण लिख सकते हैं। – hammar

उत्तर

8

दुर्भाग्यवश, आप इस बात को नियंत्रित नहीं कर सकते कि उदाहरण कैसे आयात और निर्यात किए जाते हैं; Do Haskell imports have side effects? देखें।

इसका मतलब है कि आपको यह सुनिश्चित करने के लिए अपने कोड को दोबारा करना होगा कि इंस्टेंस केवल एक फ़ाइल में परिभाषित किया गया है। आम तौर पर, फ़ाइल में एक उदाहरण को परिभाषित करना सबसे अच्छा होता है जो वर्ग या डेटा प्रकार को परिभाषित करता है - असल में, "अनाथ" उदाहरणों के बारे में भी एक चेतावनी है जो इस नियम का पालन नहीं करती है। (Orphaned instances in Haskell को अनाथ उदाहरणों से बचने के बारे में एक लंबी चर्चा के लिए देखें।)

हालांकि, अगर किसी कारण से यह असंभव है, तो आप अभी भी मनमाने ढंग से इसे रखने के लिए फ़ाइलों में से एक चुन सकते हैं या यहां तक ​​कि एक नया मॉड्यूल भी बना सकते हैं उस विशेष घटना की आवश्यकता वाली सभी फाइलों द्वारा आयात किया जाना है।

आम तौर पर, आप की संभावना है कि दो उदाहरणों अलग बातें, पसंद आया के साथ कैसे पेश होगा:

instance T Int where v = 0 
{- And in a different file: -} 
instance T Int where v = 1 

काफी हास्केल बदलते कैसे बिना वास्तव में कोई तुरंत स्पष्ट तरीका है इन दोनों को स्पष्ट करने के लिए नहीं है टाइपक्लास सिस्टम काम करता है।

चूंकि आपने स्वयं को एक उदाहरण लिखा है, बस उसे हटा दें। चूंकि यह पूर्वनिर्धारित जैसा ही है, बस उस मॉड्यूल को आयात करें जहां आपको इसे उपयोग करने की आवश्यकता है।

+0

"इसका मतलब है कि आपको यह सुनिश्चित करने के लिए अपने कोड को दोबारा करना होगा कि इंस्टेंस केवल एक फ़ाइल में परिभाषित किया गया है।" मैं यह कैसे कर सकता हूँ? मैंने 'टी' या' बी' नहीं लिखा था। – Dog

+0

ओह। फिर हाँ, यह बुरा है। यही कारण है कि आप अनाथ उदाहरण लिखना नहीं चाहते हैं। मैं उस मॉड्यूल के साथ इस बारे में एक बग फाइल करूंगा जिसमें अनाथ उदाहरण है - यानी, जिसकी कक्षा या प्रकार को परिभाषित किए बिना उदाहरण है। –

+2

@ डॉग: असल में, शायद मैंने आपकी समस्या को गलत समझा। चूंकि आपने एक उदाहरण लिखा है, बस इसे हटा दें। यदि आपको करना है तो इसे 'न्यूटाइप' के लिए लिखें। –

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