यह एफ # की कोठरी में शर्मनाक कंकाल की हुई है।
इस प्रयास करें:
> let mapPair f (x,y) = (f x, f y)
val mapPair : f:('a -> 'b) -> x:'a * y:'a -> 'b * 'b
पूरी तरह से सामान्य! स्पष्ट रूप से, समारोह आवेदन और tuples काम करते हैं। यह भी सामान्य
> let makeList a b = [a;b]
val makeList : a:'a -> b:'a -> 'a list
हममम,:
अब इस प्रयास करें। कैसे इस बारे में:
> let makeList a b = [a + b]
val makeList : a:int -> b:int -> int list
अहा, जैसे ही मैं वहाँ में एक (+)
है के रूप में, यह int
किसी कारण से हो जाता है।
के खेलते रहने दो:
> let inline makeList a b = [a + b]
val inline makeList :
a: ^a -> b: ^b -> ^c list
when (^a or ^b) : (static member (+) : ^a * ^b -> ^c)
हममम, दिलचस्प। बाहर निकलता है, अगर मैं inline
फ़ंक्शन करता हूं, तो F # इसे सामान्य मानता है, लेकिन यह इसे अजीब when
खंड भी देता है, और मेरे सामान्य पैरामीटर में सामान्य टिक के बजाय यह अजीब ^
प्रतीक है।
इस अजीब वाक्यविन्यास को "स्थिर रूप से हल किए गए प्रकार पैरामीटर" कहा जाता है (कुछ हद तक सुसंगत स्पष्टीकरण के लिए here देखें), और मूल विचार यह है कि फ़ंक्शन (+)
को इसके तर्कों को static member (+)
परिभाषित करने की आवश्यकता है।आइए सत्यापित करते हैं:
> let x = 0 :> obj
let y = 0 :> obj
let z = x + y
Script1.fsx(14,13): error FS0001: The type 'obj' does not support the operator '+'
> type My() =
static member (+)(a:My, b:My) = My()
let x = My()
let y = My()
let z = x + y
val x : My
val y : My
val z : My
अब, इस के साथ समस्या यह है कि CLR तो एफ # गया है इस सामान्य मापदंडों के प्रकार का समर्थन नहीं करता (यानी "किसी भी प्रकार, जब तक कि यह इस तरह के और इस तरह के सदस्य हैं"), है नकली इसे संकलित समय पर इन कॉलों को हल करें और हल करें। लेकिन इसके कारण, इस सुविधा का उपयोग करने वाली किसी भी विधि को वास्तविक जेनेरिक आईएल विधियों में संकलित नहीं किया जा सकता है, और इस प्रकार मोनोमोर्फिफाइड होना चाहिए (जिसे inline
द्वारा सक्षम किया गया है)।
लेकिन फिर भी, यह आवश्यकता के लिए बहुत असुविधाजनक हो सकता है कि हर कार्य अंकगणितीय ऑपरेटर inline
घोषित किया जाना का उपयोग करता है, ऐसा नहीं है? तो एफ # अभी तक एक और अतिरिक्त कदम चला गया है और इन आंकड़ों को बाद में हल किए जाने के आधार पर इन स्थिर रूप से हल किए गए जेनेरिक पैरामीटर को ठीक करने का प्रयास करता है। यही कारण है कि जैसे ही आप इसे string
के साथ उपयोग करते हैं, आपका कार्य string->string->string
में बदल जाता है।
लेकिन अगर आप अपने कार्य inline
निशान, एफ # मापदंडों ठीक करने के लिए है, क्योंकि यह समारोह आईएल के लिए नीचे संकलित करने के लिए नहीं होगा नहीं होगा, और इसलिए अपने मानकों को बरकरार रहेगा:
> let inline add a b = a + b
val inline add :
a: ^a -> b: ^b -> ^c
when (^a or ^b) : (static member (+) : ^a * ^b -> ^c)
मैं कल्पना यह एक डुप्लिकेट है; अगर मुझे पहले नहीं पूछा गया तो मुझे आश्चर्य होगा। लेकिन यह समस्या का एक उत्कृष्ट स्पष्टीकरण है। – phoog