gpt4 book ai didi

记录中的 F# 协方差和逆变

转载 作者:行者123 更新时间:2023-12-02 01:26:48 30 4
gpt4 key购买 nike

我需要描述以下关系:

type FieldDef<'Object, 'Val> { 
Name: string;
Resolve: 'Object -> 'Val
}

type ObjectDef<'Object> {
Name: string;
Fields: FieldDef<'Object, _> list
}

// example usage
type MyRecord = { X: int; Y: string; }

let myRecordDef = {
Name = "MyRecord"
Fields = [
{ Name = "x"; Resolve: fun r -> r.X }
{ Name = "y"; Resolve: fun r -> r.Y }
]
}

不幸的是, _在此用例中无效。 FieldDef 的第二类参数在这种情况下可能会有所不同 - 在 C# 中,我们可以将其注释为逆变并绑定(bind)到类型 Object .我怎样才能在 F# 中获得类似的结果而不会失去太多的类型安全性?

最佳答案

正如约翰所说,如果你想完全通用,你就会陷入类型安全的损失。然后你的 ObjectDef 类

type ObjectDef<'Object> =
{
Name: string;
Fields: FieldDef<'Object, obj> list
}

我不知道你需要“多通用”。这是一个建议,您至少可以使用一些明确表示的字段类型:您首先定义一个有区别的联合,替换您完全通用的 'Object -> 'Val :
type FieldGetter<'T> = 
| Int of ('T -> int)
| String of ('T -> string)
| AnythingElse of ('T -> obj)

然后定义一个新的字段定义记录,以及几个方便的重载:
type FieldDef2<'Object> =
{
Name: string;
Resolve: FieldGetter<'Object>
}
static member Create(name, f) = { Name = name; Resolve = Int f }
static member Create(name, f) = { Name = name; Resolve = String f }
static member Create(name, f) = { Name = name; Resolve = AnythingElse f }
type ObjectDef2<'Object> =
{
Name: string;
Fields: FieldDef2<'Object> list
}

你的例子然后变成:
let myRecordDef = {
Name = "MyRecord"
Fields = [ FieldDef2<_>.Create("x", fun r -> r.X);
FieldDef2<_>.Create("y", fun r -> r.Y) ]
}

关于记录中的 F# 协方差和逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36689257/

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