简体   繁体   中英

F# nested records

  1. Nested records

Are records similar to dictionaries where it's a tree of objects with names? Or records are just a list of simple types

let r = { b = { a = 2 } } // is this possible? if not, how to achieve? is this useful in f#?

For me with discriminated unions it's possible to achieve kind of similar behavior (code below)


// Discriminated union for a card's suit 

type Suit = | Heart | Diamond | Spade | Club 
let suits = [Heart; Diamond; Spade; Club]
suits

// Discriminated union for playing cards

type PlayingCard = 
    | Ace of Suit 
    | King of Suit 
    | Queen of Suit
    | Jack of Suit 
    | ValueCard of int * Suit

// generating a deck of cards

let deckOfCards = 
    [
        for suit in [Spade; Club; Heart; Diamond] do   
            yield Ace(suit)
            yield King(suit)
            yield Queen(suit)
            yield Jack(suit)
            for value in 2..10 do
                yield ValueCard(value, suit)
    ]

It's kind of similar to a dictionary in python or idk. The code below is dummy


type Customer = 
    {
        FirstName : string
        Contacts = 
            {
                WorkPhone : string
                MobilePhone : string
            }
        
    }

Nested types can be created using anonymous records :

type Customer = 
    {
        FirstName : string
        Contacts :
            {|
                WorkPhone : string
                MobilePhone : string
            |}
    }

let customer =
    {
        FirstName = "John"
        Contacts =
            {|
                WorkPhone = "123-456-7890"
                MobilePhone = "234-567-8901"
            |}
    }

Yes, you can have nested records, but just like in your example with discriminated unions, you need to give a name to the nested type:

type CustomerConracts =
    {
        WorkPhone : string
        MobilePhone : string
    }

type Customer = 
    {
        FirstName : string
        Contacts: CustomerConracts       
    }

let c = { FirstName = "John", Contacts = { WorkPhone = "123", Mobile phone = "098" } }

You can see some patterns in the code, but records are not similar to dictionaries. You can think of them as of classes rather, with strongly typed public properties. If you need to create a dictionary, you have to use one of the available map/dictionary classes or implement your own. Have a look at the Map type for example. https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-fsharpmap-2.html

type Contact = 
    {
        WorkPhone : string
        MobilePhone : string
    }

type Customer = 
    {
        FirstName : string
        Contacts : Contact
    }


let cust : Customer = 
    { 
      FirstName = "Joe"
      Contacts = { WorkPhone="1800131313"; MobilePhone="0863331311" } 
    }

The code above shows that you can nest the record types. Aside of using anonymous records as @brianberns suggested, you can declare the data types you plan to nest.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM