Sdílet prostřednictvím


Discriminated unií (F#)

Sdružení discriminated poskytují podporu pro hodnoty, které může být číslo pojmenované případy, případně každý s různými hodnotami a typy.Discriminated sdružení jsou užitečné pro heterogenní data; data, která mohou mít zvláštní případy, včetně platné a chyba případů; data, která se liší v typu z jedné instance a jako alternativu pro malé objekt hierarchie.Kromě toho rekurzivní discriminated unií pro stromové struktury dat používají.

type type-name =
   | case-identifier1 [of type1 [ * type2 ...]
   | case-identifier2 [of type3 [ * type4 ...]
   ...

Poznámky

Discriminated sdružení jsou podobné typy unie v jiných jazycích, ale existují rozdíly.Jako s unie typ v jazyce C++ nebo varianty v jazyce Visual Basic data uložená v hodnotě není stanovena; může být jeden z několika možností distinct.Na rozdíl od odborů v těchto jazycích jiných však možné možností je uveden případu identifikátor.Velká identifikátory jsou názvy pro různé druhy hodnot, které by mohly být objekty tohoto typu; hodnoty jsou volitelné.Pokud hodnoty nejsou k dispozici, je ekvivalentní případu výčtu případu.Pokud jsou hodnoty, každá hodnota může být jedinou hodnotu zadaného typu nebo n-tice, který agreguje hodnoty více stejných nebo různých typů.

option Je typ jednoduchého discriminated unie v knihovně core F#.option Je typ deklarován takto.

// The option type is a discriminated union.
type Option<'a> =
    | Some of 'a
    | None

Předchozí kód určuje, který typ Option discriminated unie, který má dva případy je Some a None.Some Případě má přidružené hodnoty, jejichž typ je reprezentován parametr typu 'a.None Případě nemá přiřazenu žádnou hodnotu.Tím option Určuje typ obecný typ, který má hodnotu typu některé nebo žádné hodnoty.Typ Option má také malá typu alias, option, je více běžně používá.

Identifikátory případu lze použít jako konstruktory typu discriminated unie.Například následující kód slouží k vytváření hodnot option typu.

let myOption1 = Some(10.0)
let myOption2 = Some("string")
let myOption3 = None

Velká identifikátory se používají také v porovnávání výrazy.Vzorek odpovídající výraz identifikátory stanovené hodnoty jednotlivých případů.Například v následujícím kódu x je uveden identifikátor hodnotu spojenou s Some u option typu.

let printValue opt =
    match opt with
    | Some x -> printfn "%A" x
    | None -> printfn "No value."

Za normálních okolností případu identifikátory lze bez jejich kvalifikační s názvem unie.Pokud chcete název vždy kvalifikovaný název unie, můžete aplikovat RequireQualifiedAccess unie typu definice atributu.

Pomocí Discriminated odborů namísto objektu hierarchie

Discriminated unie lze často použít jednodušší alternativou hierarchie malých objektů.Například následující discriminated unie nelze použít místo Shape základní třída, která má odvozené typy pro kruh, čtvercové, atd.

type Shape =
  // The value here is the radius.
| Circle of float
  // The value here is the side length.
| EquilateralTriangle of double
  // The value here is the side length.
| Square of double
  // The values here are the height and width.
| Rectangle of double * double

Místo virtuální metody pro výpočet plochy nebo obvod, je používán v implementaci objektově orientované, porovnávání na pobočku na příslušné vzorce můžete použít k výpočtu těchto množství.V následujícím příkladu se používají různé vzorce pro výpočet plochy v závislosti na tvaru.

let pi = 3.141592654

let area myShape =
    match myShape with
    | Circle radius -> pi * radius * radius
    | EquilateralTriangle s -> (sqrt 3.0) / 4.0 * s * s
    | Square s -> s * s
    | Rectangle (h, w) -> h * w

let radius = 15.0
let myCircle = Circle(radius)
printfn "Area of circle that has radius %f: %f" radius (area myCircle)

let squareSide = 10.0
let mySquare = Square(squareSide)
printfn "Area of square that has side %f: %f" squareSide (area mySquare)

let height, width = 5.0, 10.0
let myRectangle = Rectangle(height, width)
printfn "Area of rectangle that has height %f and width %f is %f" height width (area myRectangle)

Výstup je následující:

Area of circle that has radius 15.000000: 706.858347
Area of square that has side 10.000000: 100.000000
Area of rectangle that has height 5.000000 and width 10.000000 is 50.000000

Pomocí Discriminated unií pro Data stromové struktury

Discriminated sdružení může být rekurzivní, což znamená, že sama unie mohou být součástí typ jeden nebo více případů.Rekurzivní discriminated odbory lze použít k vytvoření stromové struktury, které se používají k modelu výrazy v programovacích jazycích.Následující kód rekurzivního discriminated unie se používá k vytvoření binárního stromové struktury dat.Unie se skládá ze dvou případů Node, což je uzel s celočíselnou hodnotu a levé a pravé podstromy a Tip, který ukončí stromu.

type Tree =
    | Tip
    | Node of int * Tree * Tree

let rec sumTree tree =
    match tree with
    | Tip -> 0
    | Node(value, left, right) ->
        value + sumTree(left) + sumTree(right)
let myTree = Node(0, Node(1, Node(2, Tip, Tip), Node(3, Tip, Tip)), Node(4, Tip, Tip))
let resultSumTree = sumTree myTree

V předchozím kódu resultSumTree má hodnotu 10.Následující obrázek znázorňuje stromové struktury pro myTree.

Stromové struktury pro myTree

Diagram stromu pro rozlišovaná sjednocení

Discriminated sdružení pracovat i v případě, že jsou heterogenní uzlů ve stromu.Následující kód typu Expression představuje strom abstraktní syntaxe výrazu v Jednoduchý programovací jazyk, který podporuje sčítání a násobení čísel a proměnné.Některé případy unie nejsou rekurzivní a představují buď čísla (Number) nebo proměnné (Variable).Ostatních případech jsou rekurzivní a představují operace (Add a Multiply), kde jsou operandy také výrazy.Evaluate Funkce použije odpovídající výraz rekurzivně procesu syntaxe stromu.

type Expression = 
    | Number of int
    | Add of Expression * Expression
    | Multiply of Expression * Expression
    | Variable of string

let rec Evaluate (env:Map<string,int>) exp = 
    match exp with
    | Number n -> n
    | Add (x, y) -> Evaluate env x + Evaluate env y
    | Multiply (x, y) -> Evaluate env x * Evaluate env y
    | Variable id    -> env.[id]

let environment = Map.ofList [ "a", 1 ;
                               "b", 2 ;
                               "c", 3 ]

// Create an expression tree that represents
// the expression: a + 2 * b.
let expressionTree1 = Add(Variable "a", Multiply(Number 2, Variable "b"))

// Evaluate the expression a + 2 * b, given the
// table of values for the variables.
let result = Evaluate environment expressionTree1

Provedení tohoto kódu, hodnoty result je 5.

Viz také

Další zdroje

F# Language Reference