2012-05-30 11 views
7

द्वारा गुणा गुणा करें शायद एक मूर्ख सवाल है, लेकिन मैं अभी एफ # के साथ शुरू कर दिया है और मुझे थोड़ा समस्या है।एफ # - फ्लोट

let multiplyByTwo x = x * 2 

जब मैं इस तरह इस फोन:

let result = multiplyByTwo 5 

सब कुछ ठीक है, परिणाम 10

है जब मैं इसे कहते

मैं इस तरह एक समारोह है कहो इस तरह:

let result = multiplyByTwo 2.5 

मुझे परिणामस्वरूप 5 या 5.0 प्राप्त होने की उम्मीद है। वास्तविक परिणाम हालांकि यह है:

परिणाम = multiplyByTwo 2.5 ;;
--------------------------------- ^^^

stdin (4,28): त्रुटि FS0001: यह अभिव्यक्ति प्रकार

int  

की उम्मीद नहीं थी, लेकिन यहाँ टाइप

float 

क्योंकि मैं इस समारोह को कुछ हद तक सामान्य होना चाहते हैं (यानी दोनों चल बिन्दु संख्या और पूर्णांकों स्वीकार करते हैं) है, मैं यह पसंद नहीं है। मेरा सवाल है: कोई इसे कैसे हल करता है?

+0

मुझे एफ # इसलिए टिप्पणी के बारे में बहुत कुछ पता नहीं है, लेकिन मुझे लगता है कि आपके फ़ंक्शन में '2' को एक इंट के रूप में माना जा रहा है और एक्स को एक इंट भी होने की उम्मीद है, क्या कोई तरीका है जिसे आप कास्ट कर सकते हैं? – RedEyedMonster

+0

'फ्लोट' और 'int' की 'असंगतता' वास्तव में मुझे बी # के साथ शुरू होने पर वास्तव में बग करने के लिए प्रयोग की जाती थी, लेकिन कुछ सालों बाद, मैं धीरे-धीरे विभिन्न प्रकार के रूप में विचार करने की उपयोगिता के लिए आ गया हूं। अक्सर यह मुझे खुद से पूछने के लिए मजबूर करता है कि मैं वास्तव में क्या चाहता हूं *। – Benjol

+0

मेरा मानना ​​है कि यह एक भाषा दोष है और मेरा कामकाज सब कुछ के लिए फ्लोट का उपयोग करना था जब मैं वास्तविक संख्याओं से निपटना चाहता हूं और प्रदर्शन या सटीकता की परवाह नहीं करता हूं। –

उत्तर

12
let inline mulBy2 x = (float x) * 2.0 

let a = mulBy2 3 // 6.0 : float 
let b = mulBy2 2.5 // 5.0 : float 
let c = mulBy2 "4" // 8.0 : float 
+0

मुझे यह तरीका सबसे साफ तरीका खोजने के लिए मिलता है। एक अच्छा समाधान की तरह लग रहा है। मैं अभी तक 'इनलाइन' कीवर्ड को पूरी तरह से समझ नहीं पा रहा हूं (ऐसा लगता है कि यह इनपुट को पार करता है, लेकिन मुझे नहीं पता कि कब उपयोग करना है और इसका उपयोग कब नहीं करना है), लेकिन मैं इसे Google पर देखूंगा। –

+1

एमएसडीएन से: "इनलाइन संशोधक के बिना, टाइप करें, फ़ंक्शन को इस मामले int में एक विशिष्ट प्रकार लेने के लिए मजबूर करता है, लेकिन इनलाइन संशोधक के साथ, फ़ंक्शन को स्थिर रूप से हल किए गए प्रकार पैरामीटर के लिए भी अनुमानित किया जाता है। इसका मतलब है कि फ़ंक्शन फ्लोट करने के लिए रूपांतरण का समर्थन करने वाले किसी भी प्रकार को स्वीकार करता है। " –

14

जब आप एफ # एक अंकीय शाब्दिक बारे में (जैसे 2 या 3.14 के रूप में), संकलक व्यवहार करता है कि और संख्यात्मक शाब्दिक का उपयोग करता है बहुरूपी नहीं होगा एक विशेष प्रकार का मान तो कोड के रूप में। आप या तो इनपुट को एक ही प्रकार में परिवर्तित कर सकते हैं और उस प्रकार के साथ काम कर सकते हैं (जैसे float डेस्को के उत्तर में) या एफ #

कुछ संख्यात्मक संचालन को पॉलिमॉर्फिक तरीके से लिखा जा सकता है, यदि आप चिह्नित करते हैं कोड inline (इस तरह, संकलक अतिरिक्त बाधाओं का प्रतिनिधित्व कर सकते हैं और उन्हें स्थिर रूप से हल कर सकते हैं) और यदि आप केवल पॉलीमोर्फिक प्राइमेटिव्स (अतिरिक्त स्थिर बाधाओं के साथ) का उपयोग करते हैं।

स्टैंडर्ड ऑपरेटरों inline कार्यों में polymorpic हैं और एफ # पुस्तकालय 1 और 0 (हालांकि नहीं 2) का प्रतिनिधित्व करने बहुरूपी मूल्य पाने के लिए एक तरीका प्रदान करता है, लेकिन वह समारोह आप चाहते थे लिखने के लिए काफी है:

let inline twoTimes n = 
    let one = LanguagePrimitives.GenericOne 
    n * (one + one) 

twoTimes 2 
twoTimes 2.0 

हैं आप इस अच्छा, तो आपको अंकीय शाब्दिक (Daniel's answer to earlier StackOverflow question देखें) परिभाषित कर सकते हैं बनाना चाहते हैं और फिर आप वास्तव में सिर्फ लिख सकते हैं:

let inline twoTimes n = n * 2G 

विशेष सांख्यिक शाब्दिक 2G एक के लिए एक कॉल करने के लिए अनुवाद किया है NumericLiteralG का फ़ंक्शन जो ऊपर उपयोग की गई तकनीक का उपयोग करके जेनेरिक 1 मानों की निर्दिष्ट संख्या का योग करता है (इसलिए यह बड़ी संख्या के लिए प्रभावी नहीं होगा!) अधिक जानकारी के लिए, आप writing generic numeric code in F# पर भी मेरे हालिया आलेख को देखते हैं।

+0

मैंने डेस्को के जवाब को स्वीकार किया क्योंकि यह सबसे आसान (और इमोहो क्लीन) समाधान है, लेकिन मैं आपके लिए महान पोस्ट का धन्यवाद करता हूं! बीटीडब्ल्यू, मैंने आपकी वेबसाइट पर पढ़ा है कि आप डॉन सिमे के छात्रों में से एक हैं, अच्छा! –

+0

अच्छा। मैंने पाया कि 'उत्तर "शाब्दिक से छुटकारा पाने के लिए कुछ होगा, हालांकि स्कूबी डू नहीं था, हालांकि यह कैसे करना है। –

+0

@LeonCullens यदि आप 'फ्लोट' होने के परिणाम से खुश हैं, तो @ डेस्को द्वारा उत्तर सबसे अच्छा विकल्प है। डॉन सिमे वास्तव में अभी भी मेरा (दूसरा) पीएचडी पर्यवेक्षक है :-)। –

-1

सोचें कि आप इस से भरे हुए हैं। टाइप को इंटरेड होने के आधार पर अनुमानित किया जाता है, आप 2 का उपयोग कर सकते हैं।0, या 2 एफ, लेकिन फिर आपके सभी परिणाम फ़्लोट होंगे।

सोचें कि आपको उसके लिए ट्यूटोरियल में गहराई से जाना है, मेरे पास नहीं है, इसलिए मैं इतना मदद नहीं कर सकता।

-1

आप "छोटे हैक्स" का उपयोग डरते नहीं हैं, तो यह उपयोगी हो सकता है:

// Copied from Core.LanguagePrimitives.IntrinsicFunctions.retype 
[<NoDynamicInvocation>] 
let inline retype (x:'a) : 'b = (# "" x : 'b #) 

let inline multiplyByTwo (x:'a) = x * (retype 2:'a) 

// use 
let result1 = multiplyByTwo 5 // 10 
let result2 = multiplyByTwo 2.5 // 5.0 

यह निर्माण सुरक्षित टाइप नहीं कर रहा है के बाद से प्रकार की जाँच के क्रम में किया जाता है। इसके अलावा, उद्धरण अपेक्षाकृत धीमी हैं।