2011-01-11 14 views
7

चारों ओर एफ # सदस्य की कमी की सुविधा कुछ खेल और इस तरह लेखन समारोह के बाद ByRef एकएफ # सदस्य की कमी +^मापदंडों

let xs = [ "123"; "456"; "999" ] |> List.map parse<int> 

मैं लिखने के लिए कोशिश कर रहा हूँ अन्य func tryParse, जो स्थैतिक विधि TryParse का उपयोग करता है और एफ # में बेहतर समर्थन के लिए 'a option प्रकार में पार्स परिणाम को लपेटता है। कुछ इस तरह संकलित नहीं करता है:

let inline tryParse s = 
    let mutable x = Unchecked.defaultof< ^a> 
    if (^a: (static member TryParse: string * ^a byref -> bool) (s, &x)) 
     then Some x else None 

त्रुटि है:

त्रुटि FS0001: यह अभिव्यक्ति 'प्रकार < ByRef के लिए एक> लेकिन यहाँ टाइप किया है उम्मीद की गई थी 'एक रेफरी

एफ # ref -cells डी यह भी काम नहीं करता:

let inline tryParse s = 
    let x = ref Unchecked.defaultof< ^a> 
    if (^a: (static member TryParse: string * ^a byref -> bool) (s, x)) 
     then Some x else None 

मैं क्या गलत कर रहा हूं?

+0

ओह में पुनः बनाना होगा, मुझे लगता है यह एक बग है ... भी, 'TryParse: string -> bool *^a' काम नहीं करता है। –

+0

यह एफ # 3.0 में तय किया गया प्रतीत होता है। – kvb

उत्तर

4

अद्यतन

यह एफ # 3.0 में ठीक किया गया प्रतीत होता है।

पुराना जवाब:

मैं स्टीफन टिप्पणी है कि यह सबसे अधिक संभावना एक बग है के साथ सहमत हैं। बाईफ प्रकारों पर कई सीमाएं हैं, इसलिए यह मेरे लिए विशेष रूप से आश्चर्यजनक नहीं है कि वे सदस्य की बाधाओं के साथ अच्छी तरह से खेल नहीं पाते हैं।

type parseDel<'a> = delegate of string * 'a byref -> bool 

type Parser< ^a when ^a : (static member TryParse: string * ^a byref -> bool)> private()= 
    static let parser = System.Delegate.CreateDelegate(typeof<parseDel<'a>>, typeof<'a>.GetMethod("TryParse", [|typeof<string>; typeof<'a>.MakeByRefType()|])) :?> parseDel<'a> 
    static member inline ParseDel = parser 

let inline tryParse (s:string) = 
    let mutable x = Unchecked.defaultof< ^a> 
    if Parser<_>.ParseDel.Invoke(s, &x) then 
    Some x 
    else None 

let one : int option = tryParse "1" 
1

मुझे लगता है कि यह एक बग भी है, सदस्य बाधाओं के साथ और प्रकार ByRef कुछ: यहाँ एक (बदसूरत) वैकल्पिक हल का उपयोग कर प्रतिबिंब है।

let inline tryParse<'a when 'a : (static member TryParse : string -> 'a byref -> bool)> s = 
    let args = [| s ; null |] 
    if typeof<'a> 
     .GetMethod("TryParse", [| typeof<string>; typeof< ^a>.MakeByRefType() |]) 
     .Invoke(null, args) = box true 
     then Some (args.[1] :?> 'a) 
     else None 

यह एक बहुत करीब है:: मैं सदस्य बाधा के हस्ताक्षर बदलकर एक थोड़ा कम बदसूरत प्रतिबिंब संस्करण बना सकते हैं

let inline tryParse< ^a when ^a: (static member TryParse: string -> ^a byref -> bool)> s = 
    let mutable x = Unchecked.defaultof<'a> 
    if (^a: (static member TryParse: string -> ^a byref -> bool) (s, &x)) 
     then Some x else None 

लेकिन मैं एक त्रुटि मिलती है FS0421: के पते परिवर्तनीय 'x' इस बिंदु पर पर उपयोग नहीं किया जा सकता है जब मैं इसे संकलित करने का प्रयास करता हूं।

1

यह संकलित लेकिन अभी भी काम नहीं करता है के रूप में उम्मीद: इस विशिष्ट मामले में

let inline tryParse< ^a when ^a: (static member TryParse: string -> ^a ref -> bool) > s = 
    let x = ref Unchecked.defaultof< ^a> 
    match (^a: (static member TryParse: string -> ^a ref -> bool) (s, x)) with 
    | false -> None 
    | true -> Some(!x) 

// returns [Some 0; Some 0; Some 0; null], so our tryParse is not retrieving the value from the ref 
let xs = [ "1"; "456"; "999"; "a" ] |> List.map tryParse<int> 

, बल्कि प्रतिबिंब का उपयोग करने से मैं सिर्फ TryParse पार्स से बाहर च #

let inline tryParse< ^a when ^a: (static member Parse: string -> ^a) > s = 
    try 
    Some(^a: (static member Parse: string -> ^a) s) 
    with 
    | exn -> None 

let xs = [ "1"; "456"; "999"; "a" ] |> List.map tryParse<int> 
+0

मैंने इसे [email protected] पर उठाया –

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