2010-07-11 7 views
7

हाल ही में कई टाइमस्पैन के साथ काम कर रहे थे, और & औसत प्राप्त करने की आवश्यकता है।
हालांकि, टाइमस्पेन न तो ऑपरेटर get_Zero और न ही DivideByInt को परिभाषित करता है, इसलिए Seq.sum और Seq.average का उपयोग सीधे इस प्रकार से नहीं किया जा सकता है।मौजूदा प्रकारों को Seq.sum, आदि के साथ काम करने के लिए बढ़ाया जा सकता है?

open System 
type System.TimeSpan 
    with 
     static member Zero with get() = TimeSpan() 
     static member (/) (n:DateTime, d:int) = DateTime(n.Ticks/(int64) d) 

let ts = [ TimeSpan(10L); TimeSpan(99L) ] 
let sum = ts |> Seq.sum 
let avg = ts |> Seq.average 
  • त्रुटि:: प्रकार 'TimeSpan' 'get_Zero'
  • त्रुटि नामित किसी भी ऑपरेटरों का समर्थन नहीं करता: प्रकार 'TimeSpan' 'DivideByInt' नाम किसी भी ऑपरेटरों का समर्थन नहीं करता निम्नलिखित संकलन करने में विफल रहता है
  • चेतावनी: एक्सटेंशन सदस्य ऑपरेटर ओवरलोड प्रदान नहीं कर सकते हैं। इसके बजाय ऑपरेटर को टाइप परिभाषा के हिस्से के रूप में परिभाषित करने पर विचार करें।

क्या कुछ एफ # जादू है जो इन ऑपरेटरों को मौजूदा प्रकार पर परिभाषित कर सकते हैं?

मुझे पता है कि निम्नलिखित काम करेंगे (और बूट करने के लिए और अधिक कुशल होना चाहिए), लेकिन मैं अभी भी ऊपर के बारे में उत्सुक हूं इसलिए मैं इसे अन्य प्रकार के उपयोग के लिए अपने टूलबॉक्स में जोड़ सकता हूं।

let sum = TimeSpan(ts |> Seq.sumBy (fun t -> t.Ticks)) 
let avg = TimeSpan(let len = ts |> Seq.length in sum.Ticks/int64 len) 
+0

'सिस्टम। टाइमस्पेन' मुहरबंद है ताकि आप इससे प्राप्त नहीं कर सकें। – gradbot

उत्तर

9

जहाँ तक मुझे पता है, स्थिर सदस्य की कमी (कि Seq.sum जैसे कार्यों के द्वारा किया जाता है) के सदस्यों को उस प्रकार एक्सटेंशन (अनिवार्य रूप से, विस्तार विधि) द्वारा जोड़ रहे हैं की खोज करने में सक्षम नहीं हैं, तो मुझे नहीं लगता कि ऐसा करने का एक सीधा तरीका है।

सबसे अच्छा विकल्प मैं सोच सकता हूं कि System.TimeSpan संरचना के आसपास एक साधारण रैपर बनाना है। फिर आप सभी आवश्यक सदस्यों को परिभाषित कर सकते हैं। कोड इस तरह दिखेगा:

[<Struct>] 
type TimeSpan(ts:System.TimeSpan) = 
    member x.TimeSpan = ts 
    new(ticks:int64) = TimeSpan(System.TimeSpan(ticks)) 
    static member Zero = TimeSpan(System.TimeSpan.Zero) 
    static member (+) (a:TimeSpan, b:TimeSpan) = 
    TimeSpan(a.TimeSpan + b.TimeSpan) 
    static member DivideByInt (n:TimeSpan, d:int) = 
    TimeSpan(n.TimeSpan.Ticks/(int64 d)) 

let ts = [ TimeSpan(10L); TimeSpan(99L) ] 
let sum = ts |> Seq.sum 
let avg = ts |> Seq.average 

मैं प्रकार TimeSpan कहा जाता है, तो यह मानक System.TimeSpan प्रकार छुपाता है। हालांकि, आपको अंतर्निहित सिस्टम प्रकार तक पहुंचने की आवश्यकता होने पर भी आपको ts.TimeSpan लिखने की आवश्यकता है, इसलिए यह उतना अच्छा नहीं है जितना हो सकता है।

+0

तो, संक्षिप्त उत्तर यह है कि "आप इसे सीधे नहीं कर सकते हैं, लेकिन प्रॉक्सी ऑब्जेक्ट के माध्यम से इसे कर सकते हैं।" ये मेरे लिए सही है। जैसा कि मैंने कहा, वर्तमान समस्या के लिए यह कोई बड़ा सौदा नहीं है, लेकिन मेरी जेब में अच्छा लगा। धन्यवाद! –

+0

बस कुछ देखा .... सिस्टम की तरह दिखता है। टाइमस्पेन में पहले से ही एक स्थिर रीड-ओनली प्रॉपर्टी है जिसे "शून्य" कहा जाता है। कोई संकेत क्यों F # शिकायत करता है कि ऐसी कोई चीज़ नहीं है? –

+2

@ जेम्स: मेरा मानना ​​है कि 'सिस्टम' में 'शून्य' वास्तव में एक क्षेत्र है - संपत्ति नहीं - और एफ # सदस्य बाधाएं केवल गुण/विधियों के साथ काम करती हैं। एक वास्तविक जीवन उदाहरण दिखाता है कि खेतों का उपयोग परेशानियों का कारण बन सकता है ...! निहित रूपांतरण की सोच के लिए –

3

एमएचएच निम्नलिखित बदसूरत है, लेकिन यह काम करता है। क्या इसने सहायता की? मैं TimeSpan के लिए एक रैपर परिभाषित करता हूं जिसे स्पष्ट रूप से TimeSpan में परिवर्तित किया जा सकता है।

type MyTimeSpan(ts : TimeSpan) = 
    member t.op_Implicit : TimeSpan = ts 
    static member (+) (t1 : MyTimeSpan, t2 : MyTimeSpan) = 
     new MyTimeSpan(TimeSpan.FromTicks(t1.op_Implicit.Ticks + t2.op_Implicit.Ticks)) 
    static member Zero = new MyTimeSpan(TimeSpan.Zero) 
    static member DivideByInt (t : MyTimeSpan, i : int) = 
     new MyTimeSpan(TimeSpan.FromTicks(int64 (float t.op_Implicit.Ticks/float i))) 

let toMyTS ts = new MyTimeSpan(ts) 

let l = [TimeSpan.FromSeconds(3.); TimeSpan.FromSeconds(4.)] 
      |> List.map toMyTS 
      |> List.average 
+0

+1। –

+0

क्या अंतर्निहित रूपांतरण वास्तव में आपको कुछ भी देता है? जहां तक ​​मुझे पता है, एफ # उन्हें अनदेखा करता है (यह कोई अंतर्निहित रूपांतरण नहीं करता है), इसलिए यह केवल तब उपयोगी होगा जब प्रकार सी # से भी उपयोग किया गया था ... –

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

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