2010-10-24 19 views
5

मैं यह देखना चाहता हूं कि एक चीज़ को दूसरे में परिवर्तित करने के लिए एक प्रकार की कक्षा है और [(a,b)] के मैपिंग से फिर से वापस लेना संभव है या नहीं।सामान्य रूपांतरण प्रकार वर्ग

इस उदाहरण को वर्णन करना चाहिए मुझे क्या करना चाहते हैं:

{-# LANGUAGE MultiParamTypeClasses #-}  
import Data.Maybe(fromJust) 

lk = flip lookup 
flipPair = uncurry $ flip (,) 

class (Eq a, Eq b) => Convert a b where 

    mapping :: [(a, b)] 
    mapping = error "No mapping defined" 

    convert :: a -> b 
    convert = fromJust . lk mapping 

-- // This won't work: 
instance (Convert a b) => Convert b a where 
    convert = fromJust . lk (map flipPair mapping) 

यह के लिए दो उदाहरणों को परिभाषित करने के साथ ऐसा करना आसान है:

data XX = One | Two | Three deriving (Show, Eq) 
data YY = Eno | Owt | Eerht deriving (Show, Eq) 

instance Convert XX YY where 
    mapping = [(One, Eno), (Two, Owt), (Three, Eerht)] 

-- // How can I make this work?: 
main = do print $ (convert One :: YY) -- Want to output: Eno 
      print $ (convert Owt :: XX) -- Want to output: Two 

यहाँ यह काम कर रही है पर मेरी वार है रूपांतरण किसी भी तरह से जा रहा है लेकिन मैं केवल पहले उदाहरण में घोषित करना चाहता हूं। कोई विचार है कि मैं यह कैसे कर सकता हूं?


संपादित करें: व्यवहार्य से मेरा मतलब है, क्या यह ओवरलैपिंग उदाहरणों के बिना किसी अन्य ग़लत एक्सटेंशन के किए जा सकता है?

उत्तर

4

मैं, एर ... मुझे लगभग यह सुझाव देने से नफरत है, क्योंकि ऐसा करना बहुत ही भयानक है, लेकिन ... क्या आपका कोड काम नहीं करता है?

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 
{-# LANGUAGE OverlappingInstances #-} 
import Data.Maybe(fromJust) 

lk x = flip lookup x 
flipPair = uncurry $ flip (,) 

class (Eq a, Eq b) => Convert a b where 
    mapping :: [(a, b)] 
    mapping = error "No mapping defined" 
    convert :: a -> b 
    convert = fromJust . lk mapping 

instance (Convert a b) => Convert b a where 
    convert = fromJust . lk (map flipPair mapping) 

data XX = One | Two | Three deriving (Show, Eq) 
data YY = Eno | Owt | Eerht deriving (Show, Eq) 

instance Convert XX YY where 
    mapping = [(One, Eno), (Two, Owt), (Three, Eerht)] 

main = do print $ (convert One :: YY) 
      print $ (convert Owt :: XX) 

और:

[1 of 1] Compiling Main    (GeneralConversion.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> main 
Eno 
Two 
*Main> 

मुझे यकीन है कि इस तरह के एक प्रकार वर्ग कितनी उपयोगी नहीं कर रहा हूँ, और संदिग्ध एक्सटेंशन के बारे में सभी मानक अस्वीकरण लागू होते हैं, लेकिन यह है कि ज्यादा काम करने के लिए लगता है। अब, यदि आप कुछ भी करना चाहते हैं fancier ... जैसे Convert a a या (Convert a b, Convert b c) => Convert a c ... चीजें अजीब हो सकती हैं।


मैं क्यों मैं इस की उपयोगिता पर संदेह मैं भी के बारे में कुछ विचार छोड़ सकता है लगता है:

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

  • error के उपयोग के लापता रूपांतरण, ऊपर के साथ संयुक्त संभालने के लिए, इसका मतलब है कि किसी भी कथित तौर पर सामान्य convert का उपयोग कर समारोह बस होने के लिए इंतजार कर रहे क्रम त्रुटियों की एक खदबदा गड्ढे हो जाएगा।

  • यह सब ऊपर बंद करने के लिए, सामान्य उदाहरण उलट मानचित्रण के लिए इस्तेमाल किया जा रहा है, वास्तव में एक सार्वभौमिक उदाहरण, केवल ओवरलैप है, और अधिक विशिष्ट उदाहरण से छिपा हुआ जा रहा है। संदर्भ में (Convert a b)? इससे उलटा मैपिंग कार्य करने देता है, लेकिन यह केवल उन उदाहरणों को उलटाने तक सीमित नहीं करता है जिन्हें विशेष रूप से परिभाषित किया गया है।

+0

सादगी के लिए, आप सभी 'LANGUAGE' pragmas को अल्पविराम से अलग सूची में जोड़ सकते हैं: '{- # LANGUAGE MultiParamTypeClasses, ... # -}'। –

+0

@ एंटल एस-जेड: हाँ, अलग-अलग रेखाएं सिर्फ मेरी आदत है। मैं हास्केल के लिए एक काफी सरल संपादक का उपयोग करता हूं और कोड को दोबारा जोड़ने के दौरान प्रागमा को जोड़ना/निकालना आसान होता है यदि वे स्वयं निहित हैं। –

+0

यह उचित है; मैंने कभी भी एक परियोजना में एक या दो से अधिक नहीं किया है, इसलिए उन्हें दोबारा सुधारना एक बड़ा मुद्दा नहीं रहा है। मैं लाभ देख सकता हूं, हालांकि, अब मैं इसके बारे में सोचता हूं। –

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