【发布时间】:2021-10-17 08:43:13
【问题描述】:
假设我有一个泛型类型,在 F# 中有一些复杂的类型约束:
[<Struct>]
type Vec2<'t when 't : equality
and 't : comparison
and 't : (static member get_Zero : Unit -> 't)
and 't : (static member (+) : 't * 't -> 't)
and 't : (static member (-) : 't * 't -> 't)
and 't : (static member (*) : 't * 't -> 't)
and 't : (static member (/) : 't * 't -> 't)> =
{
X : 't
Y : 't
}
现在我想创建另一个基于此的泛型类型:
// Does not work
[<Struct>]
type AABB<'t> =
{
Min : Vec2<'t>
Max : Vec2<'t>
}
除非我复制类型约束,否则这不起作用:
[<Struct>]
type AABB<'t when 't : equality
and 't : comparison
and 't : (static member get_Zero : Unit -> 't)
and 't : (static member (+) : 't * 't -> 't)
and 't : (static member (-) : 't * 't -> 't)
and 't : (static member (*) : 't * 't -> 't)
and 't : (static member (/) : 't * 't -> 't)> =
{
Min : Vec2<'t>
Max : Vec2<'t>
}
这很快就会变老!
有没有办法将类型约束绑定到一个名称,以便我可以在整个代码中重复使用它们?
// Not real code
constraint IsNumeric 't =
't : equality
and 't : comparison
and 't : (static member get_Zero : Unit -> 't)
and 't : (static member (+) : 't * 't -> 't)
and 't : (static member (-) : 't * 't -> 't)
and 't : (static member (*) : 't * 't -> 't)
and 't : (static member (/) : 't * 't -> 't)
[<Struct>]
type Vec2<'t when IsNumeric 't> =
{
X : 't
Y : 't
}
[<Struct>]
type AABB<'t when IsNumeric 't> =
{
Min : Vec2<'t>
Max : Vec2<'t>
}
【问题讨论】:
-
你能解释一下你的用例是什么,即为什么你不能用在你的类型上运行的内联函数来隐藏约束,最好是在一个单独的模块中?否则是一个非常有效的问题!
-
@kaefer 我想定义构成其他类型的新类型。我想将每个记录属性作为参数传递会起作用。但我认为它的可读性会降低。例如,它还可以防止构建组合类型的集合。
标签: f#