我想在实例化通用记录时显式提供类型参数。换句话说,给定 RecordType<'T1, 'T2, 'T3>
,我想创建一个 RecordType<'T1, 'T2, 'T3>
的实例有一些固定的'T1
, 'T2
和 'T3
通过指定那些通用参数。有没有办法在 F# 中做到这一点?
我看到了三种有用的情况:
假设我们有以下记录定义:
type SimpleGenericRecord<'T1, 'T2> = {
f1 : 'T1 -> 'T2
}
type SimpleGenericRecord<'T> = {
f1 : 'T -> 'T
}
我很容易构造
SimpleGenericRecord<'T>
的实例这是最后定义:
let record = {
f1 = fun (x: int) -> 0
}
let record1 = {
SimpleGenericRecord.f1 = fun (x: int) -> 0
}
以下尝试创建
SimpleGenericRecord<int, int>
给编译错误:
let record2 = {
SimpleGenericRecord<int, int>.f1 = fun (x: int) -> 0
}
let record3 = {
SimpleGenericRecord<_, _>.f1 = fun (x: int) -> 0
}
我知道为两种类型使用相同的记录名称可能不是最好的主意,但是,我认为语言应该给我一种使用这两种类型的方法。
F# reference说:
Don't use the DefaultValue attribute with record fields. A better approach is to define default instances of records with fields that are initialized to default values and then use a copy and update record expression to set any fields that differ from the default values.
按照那条建议,我想定义记录的默认实例,并且由于它们是公共(public) API 的一部分,因此记录它们的类型。
记录类型的通用参数可用于推断记录值的类型。
假设我有:
type RecordWithSomeComplexType<'T> = {
t1 : int -> System.Collections.Generic.Dictionary<int, 'T> // some long type signature
}
我想实例化它。如果我不提供任何类型注释,记录值将尽可能通用,例如
let record4 = {
RecordWithSomeComplexType.t1 = failwith "Intentionally failing"
}
有类型
int -> System.Collections.Generic.Dictionary<int, obj>
我可以强制记录为某种类型(例如
RecordWithSomeComplexType<string>
),但在这种情况下,我需要编写某个值的完整类型,例如let failing = {
RecordWithSomeComplexType.t1 =
failwith "Intentionally failing" :> int -> System.Collections.Generic.Dictionary<int, string>
// I don't want to provide a full type of a value here
}
如果编译器知道我想要
RecordWithSomeComplexType<string>
,它可以推断出值(value)的签名。 最佳答案
您几乎可以在任何地方添加类型注释
let record2 : SimpleGenericRecord<_, _> = {
f1 = fun (x: int) -> 0
}
// alternative
let record2 =
({
f1 = fun (x: int) -> 0
} : SimpleGenericRecord<_, _>)
对于更长的情况,您可以编写别名类型来简化事情
type Alias<'T> = int -> System.Collections.Generic.Dictionary<int, 'T>
let record4 = {
t1 = (failwith "Intentionally failing" : Alias<string>)
}
请注意,record4 评估将立即引发异常,因为它没有延迟
关于generics - 如何使用显式类型参数实例化通用记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39155563/