2013-10-28 4 views
5

के एक साधारण समारोह मूल्य f1 लेते हैं: के रूप मेंस्पष्ट रूप से जेनेरिक फ़ंक्शन मान समान गैर-जेनेरिक से भिन्न क्यों होता है?

*bind f1* 
val f1 : (unit -> unit) 

FSI में

let f1 = printfn "*bind f1*"; fun() -> printfn "f1()" 

f1 बांधता है और, लागू किया जा रहा, बर्ताव करता है

>() |> f1 |> f1;; 
f1() 
f1() 
val it : unit =() 

अपेक्षा के अनुरूप अब एक समान कार्य करते हैं मान, लेकिन स्पष्ट रूप से जेनेरिक f2<'a>:

let f2<'a> = printfn "*bind f2*"; fun() -> printfn "f2()" 

f2

val f2<'a> : (unit -> unit) 

रूप FSI में बांधता है किसी भी *bind f2* उत्पादन के बिना, लेकिन फिर, लागू किया जा रहा है, प्रत्येक f2 मंगलाचरण पर आउटपुट:

>() |> f2 |> f2;; 
*bind f2* 
f2() 
*bind f2* 
f2() 
val it : unit =() 

मेरा प्रश्न है: क्या हो सकता है ऐसी मनाई असमानता का कारण बनें?

+1

f2 एक प्रकार समारोह (च # कल्पना में 10.2.3) है – desco

+0

@ डेस्को: धन्यवाद, व्लादिमीर! यदि आप इसे किसी उत्तर में नहीं रखना चाहते हैं तो मुझे इसे स्वीकार करने में खुशी होगी। –

उत्तर

4

एफ # नहीं आम तौर पर क्योंकि "मूल्य प्रतिबंध" कठिनाइयों के सामान्य मूल्यों के बनाने की अनुमति देते हैं कि इस प्रस्तुत किया (जो है, यदि आप एक वाक्यात्मक मूल्य है कि सामान्य है नहीं बना सकते, भले ही यह एक कोड फ़ंक्शन कि है) । तो, अपने f2 नहीं की अनुमति दी जाना चाहिए, लेकिन ...

नियम केवल एक अपवाद है - अक्सर List.empty और इतने की तरह सामान्य मूल्यों के लिए उपयोगी है यदि आप स्पष्ट सामान्य प्रकार तर्क के साथ एक मूल्य की घोषणा यह, यह वास्तव में है एक समारोह में संकलित जो परिणाम देता है।

कि वास्तव में क्या अपने उदाहरण में क्या होता है:

let f2<'a> = printfn "*bind f2*"; fun() -> printfn "f2()" 
यहाँ

, f2 एक सामान्य मूल्य है (भले ही यह वास्तव में प्रकार तर्क कहीं भी उपयोग नहीं करता है), लेकिन यह एक स्पष्ट सामान्य प्रकार तर्क है और इसलिए यह वास्तव में एक विधि है कि हर बार f2 कहा जाता है पहुँचा जा सकता है में संकलित किया गया है और यह परिणाम (समारोह unit -> unit)

मैं विनिर्देश में इस के लिए किसी भी स्पष्ट विवरण नहीं मिल सका देता है, लेकिन वहाँ एक good MSDN article (देखें "मामला है 4 ") और एकभी।

2

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

type private Container<'a>() = 
    static member val f2 : unit -> unit = printfn "*bind f2*"; fun() -> printfn "f2()" 

let f2<'a>() = Container<'a>.f2() 
संबंधित मुद्दे