Discriminated Unions and the Record type

Discriminated Unions and Union types represent for the first time since the beginning of the chapter constructs not necessarily related to functional programming. They are essential to simplify the development of libraries and applications in F#.

The Record type is a set of simple values that are named and can optionally have members.

Their syntax is as follows:

[ attributes ] 
type [accessibility-modifier] typename = {  
    [ mutable ] label1 : type1; 
    [ mutable ] label2 : type2; 
    ... 
    } 
    member-list 

Take a look at the following example:

//Record Type 
type Point = { x : float; y: float; z: float option; }  
 
let point2D = { x = 1.0; y = 1.0; z = None} 
let point3D = { point2D with z = Some(-1.0)} 

Tip

In this example, you can see some of the syntactic features of the Record type.

The keyword option declared during the type definition indicates that value can be inserted or not. None and Some (<value>) are used precisely to indicate in the first variable not assigned a value and in the second such award, respectively.

The keyword with preceded by an identifier already valued permits passing all the values of the first variable to the declaration of the new variable. In this way, we don't have to change the values every time, but we have the advantage to replace only the values that you want to change.

The Record type might seem like a class of C #, but in reality, there are some important differences. They are as follows:

  • The fields come directly exposed as properties: in read-only by default and read-write with the keyword mutable
  • In a Record type, you cannot define a constructor
  • Importantly, the Record type, unlike classes, are compared as value types (similar to the structures of the C#) and not as reference types

Instead, Discriminated Unions provide support for tagged values with a label, forming a casuistic. In addition, each of them can have completely different values and types.

The syntax is as follows:

type type-name = 
   | case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] type2 ...] 
   | case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 ...] 

An example is as follows:

//Discriminated unions 
type Shape = 
    | Rectangle of width : float * length : float 
    | Circle of radius : float 
    | Prism of width : float * float * height : float 
 
let rect = Rectangle(length = 1.3, width = 10.0) 
let circ = Circle (1.0) 
let prism = Prism(5., 2.0, height = 3.0) 

The labelable type can be anything. If there are no values, discriminated unions are similar to the enumeration of .NET. Instead, if there are values, each of them can be a primitive type or tuple or just one Record type.

One particular development of discriminated unions is the possibility to insert them into another through the association with a label. These discriminated recursive unions are used to represent the tree structures.

In Microsoft Visual Studio, by creating a new F# project called Tutorial, you can see the sample code of most language constructs.

Here, we will report a good example of Record and Discriminated Unions type. In addition, this code portion allows us to understand the concepts discussed previously with regard to the good design and conciseness of F#. Take a look at the following example:

type Suit = | Hearts | Club | Diamonds| Spades 
    // Represents the rank of a playing card 
    type Rank =  
        | Value of int // Represents the rank of cards 2 .. 10 
        | Ace 
        | King 
        | Queen 
        | Jack 
        static member GetAllRanks() =  
            [ yield Ace 
              for i in 2 .. 10 do yield Value i 
              yield Jack 
              yield Queen 
              yield King ] 
                                    
    type Card =  { Suit: Suit; Rank: Rank } 
               
    // Returns a list representing all the cards in the deck 
    let fullDeck =  
        [ for suit in [ Hearts; Diamonds; Clubs; Spades] do 
              for rank in Rank.GetAllRanks() do 
                  yield { Suit=suit; Rank=rank } ] 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.101.81