खोज…
विभेदित संघों के भीतर टुपल्स के नामकरण तत्व
भेदभाव वाली यूनियनों को परिभाषित करते समय आप टपल प्रकार के तत्वों को नाम दे सकते हैं और पैटर्न मिलान के दौरान इन नामों का उपयोग कर सकते हैं।
type Shape =
| Circle of diameter:int
| Rectangle of width:int * height:int
let shapeIsTenWide = function
| Circle(diameter=10)
| Rectangle(width=10) -> true
| _ -> false
इसके अतिरिक्त विभेदित यूनियनों के तत्वों के नामकरण से कोड की पठनीयता में सुधार होता है और सी # के साथ अंतर-क्षमता प्रदान की जाती है, बशर्ते नाम संपत्तियों के नाम और निर्माणकर्ताओं के मापदंडों के लिए उपयोग किए जाएंगे। इंटरोप कोड में डिफ़ॉल्ट उत्पन्न नाम "आइटम", "आइटम 1", "आइटम 2" हैं ...
बुनियादी भेदभाव रहित संघ उपयोग
F # में विभेदित यूनियन प्रकारों को परिभाषित करने के लिए एक तरह से प्रस्ताव देते हैं जो किसी भी प्रकार के विभिन्न डेटा प्रकारों को पकड़ सकते हैं। उनकी कार्यक्षमता सी ++ यूनियनों या वीबी वेरिएंट के समान है, लेकिन सुरक्षित प्रकार के अतिरिक्त लाभ के साथ।
// define a discriminated union that can hold either a float or a string
type numOrString =
| F of float
| S of string
let str = S "hi" // use the S constructor to create a string
let fl = F 3.5 // use the F constructor to create a float
// you can use pattern matching to deconstruct each type
let whatType x =
match x with
| F f -> printfn "%f is a float" f
| S s -> printfn "%s is a string" s
whatType str // hi is a string
whatType fl // 3.500000 is a float
Enum- शैली यूनियनों
भेदभावपूर्ण संघ के मामलों में टाइप जानकारी शामिल करने की आवश्यकता नहीं है। प्रकार की जानकारी को छोड़ कर आप एक ऐसा संघ बना सकते हैं जो बस एक विकल्प का प्रतिनिधित्व करता है, एक एनम के समान।
// This union can represent any one day of the week but none of
// them are tied to a specific underlying F# type
type DayOfWeek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday
परावर्तन के साथ और तार से परिवर्तित
कभी-कभी एक भेदभावपूर्ण संघ को एक स्ट्रिंग से और उससे परिवर्तित करना आवश्यक होता है:
module UnionConversion
open Microsoft.FSharp.Reflection
let toString (x: 'a) =
match FSharpValue.GetUnionFields(x, typeof<'a>) with
| case, _ -> case.Name
let fromString<'a> (s : string) =
match FSharpType.GetUnionCases typeof<'a> |> Array.filter (fun case -> case.Name = s) with
| [|case|] -> Some(FSharpValue.MakeUnion(case, [||])) :?> 'a)
| _ -> None
एकल मामला भेदभावपूर्ण संघ
एक एकल भेदभाव वाला संघ किसी भी अन्य भेदभाव वाले संघ की तरह है सिवाय इसके कि उसके पास केवल एक ही मामला है।
// Define single-case discriminated union type.
type OrderId = OrderId of int
// Construct OrderId type.
let order = OrderId 123
// Deconstruct using pattern matching.
// Parentheses used so compiler doesn't think it is a function definition.
let (OrderId id) = order
यह प्रकार की सुरक्षा को लागू करने के लिए उपयोगी है और आमतौर पर F # में C # और जावा के विपरीत उपयोग किया जाता है, जहां नए प्रकार का निर्माण अधिक उपरि के साथ आता है।
निम्नलिखित दो वैकल्पिक प्रकार की परिभाषाएँ समान एकल-भेदभाव वाले संघ में घोषित की जाती हैं:
type OrderId = | OrderId of int
type OrderId =
| OrderId of int
रिकॉर्ड के रूप में एकल-मामले विरूपित यूनियनों का उपयोग करना
कभी-कभी रिकॉर्ड-प्रकार को लागू करने के लिए केवल एक मामले के साथ यूनियन प्रकार बनाना उपयोगी होता है:
type Point = Point of float * float
let point1 = Point(0.0, 3.0)
let point2 = Point(-2.5, -4.0)
ये बहुत उपयोगी हो जाते हैं क्योंकि इन्हें उसी तरह से मेल खाते हुए पैटर्न के माध्यम से विघटित किया जा सकता है जैसे कि तुच्छ तर्क कर सकते हैं:
let (Point(x1, y1)) = point1
// val x1 : float = 0.0
// val y1 : float = 3.0
let distance (Point(x1,y1)) (Point(x2,y2)) =
pown (x2-x1) 2 + pown (y2-y1) 2 |> sqrt
// val distance : Point -> Point -> float
distance point1 point2
// val it : float = 7.433034374
RequireQualifiedAccess
RequireQualifiedAccess
गए RequireQualifiedAccess
साथ, यूनियन मामलों को केवल MyCase
बजाय MyUnion.MyCase
रूप में संदर्भित किया जाना चाहिए। यह एन्कोडिंग नामस्थान या मॉड्यूल में नाम टकराव को रोकता है:
type [<RequireQualifiedAccess>] Requirements =
None | Single | All
// Uses the DU with qualified access
let noRequirements = Requirements.None
// Here, None still refers to the standard F# option case
let getNothing () = None
// Compiler error unless All has been defined elsewhere
let invalid = All
हैं, उदाहरण के लिए, System
खोल दिया गया है, Single
के लिए संदर्भित करता System.Single
। यूनियन केस Requirements.Single
साथ कोई टकराव नहीं है।
रिकर्सिव ने भेदभाव किया
पुनरावर्ती प्रकार
विभेदित संघ पुनरावर्ती हो सकते हैं, अर्थात वे अपनी परिभाषा में स्वयं को संदर्भित कर सकते हैं। यहां का प्रमुख उदाहरण एक पेड़ है:
type Tree =
| Branch of int * Tree list
| Leaf of int
एक उदाहरण के रूप में, आइए निम्नलिखित पेड़ को परिभाषित करें:
1
2 5
3 4
हम अपने पुनरावर्ती भेदभाव वाले संघ का उपयोग करके इस पेड़ को परिभाषित कर सकते हैं:
let leaf1 = Leaf 3
let leaf2 = Leaf 4
let leaf3 = Leaf 5
let branch1 = Branch (2, [leaf1; leaf2])
let tip = Branch (1, [branch1; leaf3])
पेड़ पर फेरबदल तब पैटर्न मिलान की बात है:
let rec toList tree =
match tree with
| Leaf x -> [x]
| Branch (x, xs) -> x :: (List.collect toList xs)
let treeAsList = toList tip // [1; 2; 3; 4; 5]
पारस्परिक रूप से निर्भर पुनरावर्ती प्रकार
पुनरावृत्ति को प्राप्त करने का एक तरीका है, पारस्परिक रूप से निर्भर प्रकारों का घोंसला बनाना।
// BAD
type Arithmetic = {left: Expression; op:string; right: Expression}
// illegal because until this point, Expression is undefined
type Expression =
| LiteralExpr of obj
| ArithmeticExpr of Arithmetic
एक विभेदित संघ के अंदर सीधे रिकॉर्ड प्रकार को परिभाषित करना पदावनत है:
// BAD
type Expression =
| LiteralExpr of obj
| ArithmeticExpr of {left: Expression; op:string; right: Expression}
// illegal in recent F# versions
आप and
कीवर्ड का उपयोग परस्पर निर्भर परिभाषाओं की श्रृंखला के लिए कर सकते हैं:
// GOOD
type Arithmetic = {left: Expression; op:string; right: Expression}
and Expression =
| LiteralExpr of obj
| ArithmeticExpr of Arithmetic