2015-07-12 7 views
6

मेरे पास 3 डी वेक्टर डेटा प्रकार 3 फ्लोट्स के रूप में परिभाषित किया गया है। मैं समझता हूं कि अगर मैं अपनी कक्षा के लिए Num उदाहरण प्रदान करता हूं और सामान्य गणितीय ऑपरेटरों को परिभाषित करता हूं, तो मैं उन्हें अपनी कक्षा में उपयोग कर सकता हूं।क्यों राशि को GHC.Num.fromInteger की आवश्यकता है?

data Vec3 = Vec3 { x :: Float 
       , y :: Float 
       , z :: Float 
       } deriving (Show, Eq) 

instance Num Vec3 where 
    (+) v1 v2 = Vec3 (x v1 + x v2) (y v1 + y v2) (z v1 + z v2) 

जब मैं GHCi में मेरी फाइल को लोड, मैं चेतावनी मिल क्योंकि मैं Num में सभी कार्यों को परिभाषित नहीं किया है, जो समझ में आता है।

Prelude> :l temp.hs 
[1 of 1] Compiling Main    (temp.hs, interpreted) 

temp.hs:6:10: Warning: 
    No explicit method or default declaration for `*' 
    In the instance declaration for `Num Vec3' 

temp.hs:6:10: Warning: 
    No explicit method or default declaration for `abs' 
    In the instance declaration for `Num Vec3' 

temp.hs:6:10: Warning: 
    No explicit method or default declaration for `signum' 
    In the instance declaration for `Num Vec3' 

temp.hs:6:10: Warning: 
    No explicit method or default declaration for `fromInteger' 
    In the instance declaration for `Num Vec3' 
Ok, modules loaded: Main. 

हालांकि, मैं अभी भी उन लोगों का उपयोग कर सकता हूं जिन्हें मैंने परिभाषित किया है।

*Main> let a = Vec3 1.0 2.0 3.0 
*Main> let b = Vec3 2.0 4.0 5.0 
*Main> a + b 
Vec3 {x = 3.0, y = 6.0, z = 8.0} 

मेरे भ्रम जब योग समारोह

*Main> sum [a,b] 
Vec3 {x = *** Exception: temp.hs:6:10-17: No instance nor default method for class operation GHC.Num.fromInteger 

उपयोग करने के लिए क्यों योग मेरी Vec3 डेटा प्रकार के लिए एक fromInteger परिभाषा की जरूरत है की कोशिश कर निम्न त्रुटि मैं से आता है? एक के लिए, मुझे लगता होगा कि योग केवल + फ़ंक्शन का उपयोग करता है, और दूसरे के लिए, मेरा डेटा प्रकार Integer का उपयोग नहीं करता है।

+0

आपको कक्षा के उदाहरण के रूप में डेटा प्रकार पर विचार करने से पहले हमेशा ** सभी ** संचालन को न्यूनतम पूर्ण परिभाषा में परिभाषित करना चाहिए ... – Bakuriu

+2

वास्तविक समस्या यह है कि आप 'Vec3' को 'Num'' का उदाहरण बना रहे हैं, भले ही वेक्टर संख्याएं न हों। – rightfold

+0

@ राइटफोल्ड पर विस्तार करने के लिए - नम के कुछ उदाहरण न दें क्योंकि आप चाहते हैं + - वेक्टर संख्याएं नहीं हैं, भले ही आप ऑपरेटरों में से कुछ ऑपरेटरों को संख्या ऑपरेटर के समान नाम दें। (यद्यपि आप 'वेक्टर' द्वारा संख्याओं के रूप में वेक्टरों के रूप में _can_ का इलाज करते हैं, तो आप केवल ज्यामितीय या भौतिक भावना में वेक्टर के बजाय 'संख्याओं का निश्चित आकार संग्रह' का मतलब रखते हैं)। – Cubic

उत्तर

9

यहाँ कैसे योग कार्यान्वित किया जाता है है:

sum = foldl (+) 0 

सूचना 0 शाब्दिक। यह GHCi में टाइप है जाँच करें:

λ> :t 0 
0 :: Num a => a 

यह पता चला है के रूप में, संख्यात्मक शाब्दिक fromInteger के लिए चीनी हैं। आईई, 0 वास्तव में fromInteger 0 है। ,

instance Num Vec3 where 
    fromInteger n = let a = (fromInteger n) in Vec3 a a a 

इसके अलावा मैं अत्यधिक है कि सिफारिश करेंगे,:

इस प्रकार, sumfromInteger, आवश्यकता है क्योंकि उपरोक्त परिभाषा के लिए चीनी है:

sum = foldl (+) (fromInteger 0) 

fromInteger की प्रक्रिया आसान है जब भी कोई उदाहरण बनाते हैं, तो हमेशा इस तरह की अप्रत्याशित परेशानी से बचने के लिए इसे पूरी तरह से परिभाषित करें।

+1

यह समझ में आता है। टेंगेंशियल सवाल, लेकिन मुझे इन सामान्य कार्यों के कार्यान्वयन कहां मिलते हैं? मैंने देखने की कोशिश की, लेकिन यह नहीं पता था कि – user3288829

+0

@ user3288829 https://www.haskell.org/hoogle/?hoogle=sum – phadej

+0

@ user3288829 स्रोत फ़ाइल ['GHC.Num'] है (https: // hackage.haskell.org/package/base-4.7.0.2/docs/src/GHC-Num.html)। – AJFarmar

4

sum [] :: Vec3 वापसी क्या चाहिए?


sum समारोह, के रूप में

sum :: (Num a) => [a] -> a 
sum = foldl (+) 0 

0 वहाँ वास्तव में है fromInteger (0 :: Integer) में परिभाषित किया जा सकता है इस प्रकार आप fromInteger जरूरत sum उपयोग करने के लिए।

असल में आधार 4.8 sumSumMonoid और Foldable के संदर्भ में परिभाषित किया गया है, लेकिन वह अलग कहानी है। आपको अभी भी fromInteger (0 :: Integer) की आवश्यकता है।

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