2012-03-28 8 views
6

में एक डबल के साथ एक परिसर डबल गुणा मैं जब निम्नलिखित कोड संकलन नहीं होगा थोड़ा हैरान था:हास्केल

-- Code 1 
import Complex 
type Velocity = Complex Double 
type Force = Complex Double 
type FrictionCoeff = Double 

frictionForce :: FrictionCoeff -> Velocity -> Force 
frictionForce mu vel = mu * vel 

त्रुटि का कहना है

Couldn't match expected type `Complex Double' 
      with actual type `Double' 
Expected type: Force 
Actual type: FrictionCoeff 
In the first argument of `(*)', namely `mu' 
In the expression: mu * vel 

तो, कम

में
-- Code 2 
let z = 1 :+ 2 
z * 3  -- Goes fine. 
z * 2.5 -- Goes fine. 
z * (2.5 :: Double) -- Explodes. 

कॉम्प्लेक्स परिभाषित करता है (*)

instance (RealFloat a) => Num (Complex a) where 
    (x:+y) * (x':+y') = (x*x'-y*y') :+ (x*y'+y*x') 

क्यों 3 (न्यू ए => ए) और 2.5 (फ्रैक्शनल ए => ए) पैटर्न के साथ मिलान किया जा सकता है (x: + y), लेकिन एक डबल नहीं कर सकता है?

+2

ध्यान दें कि इसका पैटर्न मिलान के साथ कुछ लेना देना नहीं है। * एकीकरण * सही शब्द हो सकता है। आप कह सकते हैं कि 'Num a => a'' जटिल डबल 'के साथ अपरिहार्य है, लेकिन' डबल' नहीं है। – Rotsor

+0

वैसे भी जटिल वेगों के साथ आप क्या कर रहे हैं? ऐसा कुछ ऐसा लगता है जो वास्तव में एक वेक्टर होना चाहिए। – leftaroundabout

+0

परिसर अंतर्निहित हैं और चरण, परिमाण और सभी को प्राप्त करने के लिए बहुत ही आसान कार्यों के साथ आते हैं। मुझे पहिया का पुन: आविष्कार करने की तरह महसूस नहीं होता है। क्या 2 डी वैक्टर के लिए एक लाइब्रेरी है जिसका मैं उपयोग कर सकता हूं? – Niriel

उत्तर

15

पहले, गुणा ऑपरेटर के प्रकार

(*) :: Num a => a -> a -> a 

जिसका अर्थ है कि आप केवल एक ही प्रकार, जिसके कारण एक Double द्वारा एक Complex Double गुणा काम नहीं करेगा की संख्याओं को गुणा कर सकते हैं।

तो दशमलव अक्षर के साथ जटिल संख्या गुणा क्यों करता है?

यह काम करता है क्योंकि संख्यात्मक अक्षर हास्केल में बहुलक होते हैं, इसलिए जब आप 42 की तरह एक पूर्णांक अक्षर टाइप करते हैं, तो इसका वास्तव में fromInteger 42 है। इसी प्रकार, 2.3 जैसे दशमलव अक्षर fromRational (23 % 10) बन जाते हैं। आप उन कार्यों के प्रकार,

fromInteger :: Num a => Integer -> a 
fromRational :: Fractional a => Rational -> a 

इसका मतलब यह है की जांच-पड़ताल कि पूर्णांक शाब्दिक, किसी भी सांख्यिक प्रकार हो सकता है दशमलव शाब्दिक किसी भी आंशिक प्रकार हो सकता है, जबकि। जटिल संख्या दोनों हैं, यही कारण है कि z * 3 और z * 2.5 दोनों काम करते हैं।

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

frictionForce :: FrictionCoeff -> Velocity -> Force 
frictionForce mu vel = (mu :+ 0) * vel 

, ढूँढना उचित रूपांतरण समारोह Hoogle का उपयोग कर आसान है जब से तुम प्रकार के आधार पर कार्यों के लिए खोज सकते हैं। इस मामले में, Double -> Complex Double के लिए खोज शीर्ष परिणाम के रूप में (:+) देता है।

7

आप "असली गणित" में भी एक जटिल संख्या के साथ वास्तविक संख्या को गुणा नहीं कर सकते हैं; जब आप 2 * (2 + 3i) लेना चाहते हैं, तो आप वास्तव में गणना करते हैं (2 + 0i) * (2 + 3i)। इसी तरह, हास्केल, में जब आप कहते हैं:

let z = 1 :+ 2 
z * 3 

... तो 3 एक Complex Double में भी परिवर्तित हो जाता है, काल्पनिक हिस्सा शून्य बना रही है। यह केवल शास्त्रीय संख्याओं के लिए होता है (2, 3.141 आदि) हास्केल की अधिभारित शाब्दिक कार्यक्षमता के कारण; चूंकि शाब्दिकों में डिफ़ॉल्ट प्रकार नहीं होता है (वे किसी भी प्रकार के मानों का प्रतिनिधित्व कर सकते हैं), हास्केल कह सकता है कि में इस संदर्भ में Complex Double टाइप किया गया है, और उपयुक्त रूपांतरण फ़ंक्शंस स्वचालित रूप से कॉल किए जाते हैं।

यदि आप मैन्युअल रूप से यह रूपांतरण करना चाहते हैं, तो एक वास्तविक संख्या से एक जटिल संख्या बनाएं जो कि एक चर या अन्यथा पहले से ही एक अलग निश्चित प्रकार है, आपको realToFrac फ़ंक्शन का उपयोग करना होगा, जो किसी भी वास्तविक को परिवर्तित करता है किसी भी आंशिक संख्या में संख्या (और Complex इस मामले में एक आंशिक संख्या के रूप में गिना जाता है)।

z * realToFrac (2.5 :: Double) 

आप निश्चित रूप से मैन्युअल रूप से भी :+ 0 जोड़ सकते हैं कि अगर आप के लिए neater लग रहा।

+4

मुझे नहीं लगता कि यह सच है। 2 + 0i 2 के समान है! "असली गणित" में वास्तविक जटिल परिसरों का एक उपन्यास है, इसलिए यह बस काम करता है। यह हास्केल, आप इस रिश्ते को व्यक्त कर सकते हैं, लेकिन आपको इंजेक्शन के बारे में स्पष्ट होना चाहिए। असल में ऐसा इसलिए है क्योंकि हमारे पास हास्केल में उपप्रकार नहीं हैं, इसलिए हम स्पष्ट रूप से स्पष्ट रूप से शामिल होने का प्रतिनिधित्व करते हैं। – sclv

+0

एक जटिल संख्या एक संख्या है जिसे एक + द्विपक्षीय रूप में रखा जा सकता है, जहां ए और बी वास्तविक संख्या हैं और मुझे काल्पनिक इकाई कहा जाता है, जहां मैं^2 = -1। दो जटिल संख्याओं के गुणा को निम्नलिखित सूत्र द्वारा परिभाषित किया गया है: '(ए + द्वि) (सी + डी) = (एसी-बीडी) + (बीसी + विज्ञापन) i'। तो जटिल संख्याएं एक अंगूठी बनाती हैं जो आर^2 का आंतरिक उत्पाद है जैसा आप कहते हैं; हालांकि, गुणा केवल दो जटिल संख्याओं के बीच परिभाषित किया गया है जिसमें वास्तविक संख्याओं की एक जोड़ी शामिल है, इसलिए '2' और' 2 + 0i' बराबर हैं, फिर भी कोई जटिल संख्या के उत्पाद की गणना नहीं कर सकता है और वास्तविक संख्या '2' परिभाषा बदल रहा है। – dflemstr

+1

"एक जटिल संख्या एक संख्या है जिसे फ़ॉर्म _a_ + _b⋅i_ में रखा जा सकता है, जहां _a_ और _b_ वास्तविक संख्याएं हैं" बिल्कुल। और चूंकि 0 अतिरिक्त के तटस्थ तत्व है, _a_ + 0 _i_ = _a_ ε ℝ। इसलिए एक जटिल और वास्तविक संख्या के बीच गुणा गणितीय ध्वनि है। परिभाषा को बदलने के लिए कैसे जरूरी है, अगर हम सिर्फ वास्तविक संख्या _a_ लिख सकते हैं _a_ + 0 _i_? – leftaroundabout