gpt4 book ai didi

types - F# 成员对返回类型的约束

转载 作者:行者123 更新时间:2023-12-01 09:21:43 25 4
gpt4 key购买 nike

假设我有以下类型:

type AddressLow = {
FlatNo: int
PinCode: string
}

type AddressHigh = {
FlatNo: int
AreaName: string
PinCode: string
}

type PersonDataLow = {
id:int
name:string
address: AddressLow
}

type PersonDataHigh = { //same label names, different type for address
id:int
name:string
address: AddressHigh
}

下面两个函数是建立地址:

let GetAddressLow () =
{AddressLow.FlatNo = 10; PinCode = "5245"}

let GetAddressHigh () =
{AddressHigh.FlatNo = 10; AreaName = "Bel Air"; PinCode = "8225"}

以下函数是构建PersonData:

let GetPerson fGetAddress inputId inputName = //return type inferred as PersonDataHigh
{
id = inputId
name = inputName
address = fGetAddress()
}

let p1 = GetPerson GetAddressLow 4 "John Smith" //compile error
let p2 = GetPerson GetAddressHigh 6 "Will Smith" //works

对于上述函数,返回类型被 F# 推断为 PersonDataHigh。因此,要返回不同类型的 PersonData(即 PersonDataHighPersonDataLow),我必须编写两个不同的函数。

另一种方法是使用区分联合 (DU),但这涉及 DU 类型和 DU 类型的案例标识符之间来回转换的次数。

是否可以对返回类型使用约束,以便只编写一次函数?比如说,像这样:

let inline GetPerson (fGetAddress) (inputId) (inputName) 
: ^T when ^T: (member id: int) and ^T: (member name: string) and (^T: (member address: AddressLow) or ^T: (member address: AddressHigh)) = //compile error
{
id = inputId
name = inputName
address = fGetAddress()
}

如果不是,那么在这里使用 DU 是不是最好的选择?我正在使用 F# 3.0。

谢谢。

最佳答案

您是否考虑过将 low 或 highness 嵌套在单个 Address 类型中?

由于您的大部分数据在两种类型的 Address 之间共享,我认为将其设为可区分联合或两种不同类型不是最明智的选择。相反,只需将其属性之一设为可区分的联合即可。

最简单的方法是将AreaName 设为选项

type Address = {
FlatNo: int
AreaName : string option
PinCode: string
}

type PersonData = {
id:int
name:string
address: Address
}

然后你可以去:

let GetAddressLow () =
{FlatNo = 10; AreaName = None; PinCode = "5245"}

let GetAddressHigh () =
{FlatNo = 10; AreaName = Some "Bel Air"; PinCode = "8225"}

然后您不需要任何花哨的东西来创建您的 GetPerson 函数。

关于types - F# 成员对返回类型的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45081993/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com