【问题标题】:Syntax: Function to return parameter of a discriminated union in F#? (Pattern match on function parameter)语法:在 F# 中返回可区分联合的参数的函数? (函数参数的模式匹配)
【发布时间】:2020-08-22 17:40:56
【问题描述】:

我显然是 F# 的新手。来自 C#,我在区分联合方面遇到了困难。

假设 F# 中有以下定义:

type Details =
            | ContactDetails of ContactDetail * id: Guid
            | Internet       of Internet  * id: Guid    
            | PhoneNumbers   of PhoneNumber  * id: Guid 
            | Addresses      of Address     * id: Guid  
    
        let contactDetail  : ContactDetail = {Name="Contact Detail"; Content="Content for Contact Detail"; Text="here is the contact detail text" }    
        let internet       : Internet = {Name="Internet";       Content="Content for Internet";       Text="here is the internet text" }
        let phoneNumber    : PhoneNumber =  {Name="Phone Number";   Content="Content for phone number";   Text="here is the phone number text" }
        let address        : Address = {Name="Address";        Content="Content for Address";        Text="here is the Address text" }
       
        let details   = [ContactDetails (contactDetail,Guid.NewGuid())
                         Internet       (internet,Guid.NewGuid())
                         PhoneNumbers   (phoneNumber,Guid.NewGuid())
                         Addresses      (address,Guid.NewGuid())
                         ]


type Model = {
      Details: Details list
    }

如何编写接收模型并返回列表中每个项目的id的函数?

例如:

有趣的细节 -> detail.id

“详细信息”类型未定义字段、构造函数或成员“id”

TIA

编辑#1:

新模型是:

类型模型 = { 详细信息:DetailsWithId 列表 }

【问题讨论】:

    标签: f#


    【解决方案1】:

    Discriminate Union 中的“Discriminated”意味着每个字段定义都被认为是彼此不同的,这就是为什么即使您有一个公共字段,也不能直接访问它。

    我通常做的最简单的事情是创建一个安全地提取该字段的扩展函数。

    type Details =
                | ContactDetails of ContactDetail * id: Guid
                | Internet       of Internet  * id: Guid    
                | PhoneNumbers   of PhoneNumber  * id: Guid 
                | Addresses      of Address     * id: Guid  
    
        member this.id = 
            match this with
            | ContactDetail(_, id)
            | Internet(_, id)
            | PhoneNumber(_, id)
            | Address(_, id) -> id
    

    另一种选择是以不同方式构建数据:

    type Details =
         | ContactDetails of ContactDetail
         | Internet       of Internet
         | PhoneNumbers   of PhoneNumber
         | Addresses      of Address
    
    // Each instance will hold one of ContactDetails, Internet, Phonenumber, and
    // each has a common property of ID (the Guid). This way, you simplify your model
    type DetailsWithId = DetailsWithId of Details * Guid
    

    另外一句话:你对DU的每个成员使用复数形式,但定义只允许一个项目。

    【讨论】:

    • 第二种方法确实是我正在尝试的方法,但无法正确使用。谢谢。
    • 你能展示一下 DetailsWithId 是如何初始化的吗?我的速度很快。
    • @AlanWayne,如果你有一个Details 实例,我们称之为dtl,还有一个Guid,我们称之为id,你可以通过以下方式创建一个DetailsWithId 实例使用正常的元组语法:let dtlWithId = DetailsWithId(dtl, id).
    猜你喜欢
    • 2015-10-19
    • 2017-03-29
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多