2012-12-04 19 views
6

का कार्य ठीक है, मैं अपने सिर को टाइपक्लास के चारों ओर लपेटने की कोशिश कर रहा हूं, और इसलिए मैं ज्यामितीय वेक्टर परिचालनों के लिए टाइपक्लास को परिभाषित करने की कोशिश कर रहा हूं। मैं घटक-वार +,-,*,/; के लिए काम करने में कामयाब रहा लेकिन मैं डॉट उत्पाद के साथ संघर्ष कर रहा हूं।हास्केल वेक्टर टाइपक्लास: [ए] -> [ए] ->

class GeomVector a where 
    (>+) :: a -> a -> a 
    (>-) :: a -> a -> a 
    (>*) :: a -> a -> a 
    (>/) :: a -> a -> a 

    (>.) :: a -> a -> Double 

data Vector a = Vec [a] 
       deriving Show 

instance (Fractional a) => GeomVector (Vector a) where 
    (>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v 
    (>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v 
    (>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v 
    (>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v 

    (>.) (Vec u) (Vec v) = sum $ u >* v 

जाहिर है के लिए (>।) काम नहीं करेगा क्योंकि परिणाम प्रकार Fractional a, नहीं Double की है मेरे उदाहरण परिभाषा।

लेकिन मुझे नहीं पता कि इस व्यवहार को कक्षा में घोषणा से कैसे प्राप्त किया जाए।

क्या मैं तरह चाहते करने के लिए है:

class GeomVector [a] where 
    (>.) :: [a] -> [a] -> a 

लेकिन यह अमान्य है क्योंकि [a] एक प्रकार है और एक प्रकार चर रहा है।

मेरी इच्छा है कि मैं इसे थोड़ा बेहतर समझा सकता हूं, लेकिन मैं ईमानदारी से ऐसा करने के लिए पर्याप्त समझ में नहीं आता हूं। उम्मीद है कि कोड इसे थोड़ा और स्पष्ट कर देगा कि मैं किसके साथ संघर्ष कर रहा हूं।

class GeomVector v where 
    (>+) :: Num a=> v a -> v a -> v a 
    (>-) :: Num a=> v a -> v a -> v a 
    (>*) :: Num a=> v a -> v a -> v a 
    (>/) :: Fractional a=> v a -> v a -> v a 
    (>.) :: Num a=> v a -> v a -> a 

data Vector a = Vec { vecList :: [a] } 
       deriving Show 

instance GeomVector Vector where 
    (>+) (Vec u) (Vec v) = Vec $ zipWith (+) u v 
    (>-) (Vec u) (Vec v) = Vec $ zipWith (-) u v 
    (>*) (Vec u) (Vec v) = Vec $ zipWith (*) u v 
    (>/) (Vec u) (Vec v) = Vec $ zipWith (/) u v 

    (>.) u v = sum $ vecList (u >* v) 

तो GeomVector के सभी अपने उदाहरणों Monad वर्ग की तरह एक प्रकार * -> * होगा:

+1

मुझे लगता है कि आपको स्केलर्स के प्रकार को इंगित करने के लिए एक और प्रकार की चर की आवश्यकता है, यानी 'क्लास जियोम वेक्टर जहां एक ... (>।) :: a -> a -> s'। – ErikR

+2

आप जो चाहते हैं वह है [एसोसिएटेड प्रकार समानार्थक] (http://www.haskell.org/haskellwiki/GHC/Type_families#An_associated_type_synonym_example) – Lambdageek

+0

आपकी कक्षा घोषणा न केवल (>।) परिणाम प्रकार के कारण त्रुटिपूर्ण है। आप '' 'u''' और' ''''' के डॉट उत्पाद का उत्पादन करने के लिए प्रयास करते हैं जो सूचियां हैं, न कि आपकी कक्षा के उदाहरण। –

उत्तर

5

यहाँ एक विकल्प है कि काम कर सकता है। और विधियों के प्रकार अनावश्यक रूप से Fractional प्रकारों तक सीमित नहीं हैं क्योंकि आप वहां कहीं भी विभाजित होते हैं।

आप अपनी कक्षा को जितना संभव हो सके छोटे बनाने पर विचार कर सकते हैं (कक्षा के बाहर >. एक पॉलिमॉर्फिक फ़ंक्शन बनाएं) और चाहे आप वास्तव में क्या चाहते हैं, एक प्रकार की कक्षा शुरू हो। लेकिन यह सब जो आप डिजाइन कर रहे हैं उस पर निर्भर करता है, और मैं यह नहीं मानना ​​चाहता कि मैं इसके बारे में आपके से बेहतर जानता हूं!

+0

क्लास से '> .' को स्थानांतरित करना संभव नहीं है, क्योंकि इसे योग करने के लिए 'जियोमवेक्टर' के प्रत्येक उदाहरण की आंतरिक संरचना के बारे में जानना आवश्यक है। – huon

+1

उस समस्या को 'toList' जोड़कर हल किया जा सकता है। –

+0

सही, क्षमा करें। तो एक विकल्प वर्ग वर्ग (Foldable v) => GeomVector v' बनाना होगा यदि यह समझ में आता है। – jberryman

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