अपडेट करें
मुझे ($)
एक सदस्य के बजाय एक ऑपरेटर का उपयोग करके एक सरल संस्करण मिला । Https://stackoverflow.com/a/7224269/4550898 से प्रेरित :
type SumOperations = SumOperations
let inline getSum b = SumOperations $ b // <-- puting this here avoids defaulting to int
type SumOperations with
static member inline ($) (SumOperations, x : int ) = x
static member inline ($) (SumOperations, xl : _ list) = xl |> List.sumBy getSum
बाकी विवरण अभी भी लागू है और यह उपयोगी है ...
मुझे इसे संभव बनाने का एक तरीका मिला:
let inline getSum0< ^t, ^a when (^t or ^a) : (static member Sum : ^a -> int)> a : int =
((^t or ^a) : (static member Sum : ^a -> int) a)
type SumOperations =
static member inline Sum( x : float ) = int x
static member inline Sum( x : int ) = x
static member inline Sum(lx : _ list) = lx |> List.sumBy getSum0<SumOperations, _>
let inline getSum x = getSum0<SumOperations, _> x
2 |> getSum |> printfn "%d" // = 2
[ 2 ; 1 ] |> getSum |> printfn "%d" // = 3
[[2; 3] ; [4; 5] ] |> getSum |> printfn "%d" // = 14
अपना उदाहरण चलाना:
let list v = List.replicate 6 v
1
|> list |> list |> list |> list |> list
|> list |> list |> list |> list |> list
|> getSum |> printfn "%d" // = 60466176
यह सदस्य बाधाओं के साथ SRTP का उपयोग करने पर आधारित है: static member Sum
बाधा को Sum
उस रिटर्न को भेजने वाले सदस्य के प्रकार की आवश्यकता होती है int
। SRTPs का उपयोग करते समय सामान्य कार्य करने की आवश्यकता है inline
।
वह कठिन हिस्सा नहीं है। कठिन हिस्सा Sum
एक मौजूदा प्रकार जैसे " सदस्य " को जोड़ना int
और List
जिसकी अनुमति नहीं है। लेकिन, हम इसे एक नए प्रकार में जोड़ सकते हैं SumOperations
और बाधा में शामिल कर सकते हैं (^t or ^a)
जहां ^t
हमेशा होने वाला है SumOperations
।
getSum0
Sum
सदस्य बाधा घोषित करता है और उसे आमंत्रित करता है।
getSum
SumOperations
पहले प्रकार के पैरामीटर के रूप में पास करता हैgetSum0
static member inline Sum(x : float ) = int x
कंपाइलर को जेनरिक डायनामिक फंक्शन कॉल का उपयोग करने के लिए समझाने के लिए लाइन जोड़ी गई और कॉल करते static member inline Sum(x : int )
समय डिफ़ॉल्ट नहींList.sumBy
जैसा कि आप देख सकते हैं कि यह थोड़ा जटिल है, वाक्यविन्यास जटिल है और संकलक पर कुछ क्विरक्स के आसपास काम करना आवश्यक था लेकिन अंत में यह संभव था।
इस विधि को अधिक परिभाषाएँ जोड़कर Arrays, tuples, विकल्प, या उनमें से किसी भी संयोजन के साथ काम करने के लिए बढ़ाया जा सकता है SumOperations
:
type SumOperations with
static member inline ($) (SumOperations, lx : _ [] ) = lx |> Array.sumBy getSum
static member inline ($) (SumOperations, a : ^a * ^b ) = match a with a, b -> getSum a + getSum b
static member inline ($) (SumOperations, ox : _ option) = ox |> Option.map getSum |> Option.defaultValue 0
(Some 3, [| 2 ; 1 |]) |> getSum |> printfn "%d" // = 6
https://dotnetfiddle.net/03rVWT
getSum (dictList (dictList (..... (dictList dictInt)))) nestedList
जहां टाइप के प्रकार मेंdictList
मैच की संख्या होती[]
हैnestedList
।