Generics 带有类型约束的简单F#运行时泛型函数可以';无法解决

Generics 带有类型约束的简单F#运行时泛型函数可以';无法解决,generics,f#,inline,type-inference,Generics,F#,Inline,Type Inference,我有一个带有一个通用参数的基本函数: let func<'T> (x:'T when 'T : (static member op_Explicit: 'T -> float) ) = float x 但是在这种情况下,x的类型被推断为int。多亏了@ildjarn,我找到了答案: 发件人: 静态解析的类型参数主要与成员约束结合使用,成员约束允许您指定类型参数必须具有特定成员才能使用。使用常规泛型类型参数无法创建此类约束 Visual Studio似乎应该给出不同的错误

我有一个带有一个通用参数的基本函数:

let func<'T> (x:'T when 'T : (static member op_Explicit: 'T -> float) ) =
   float x

但是在这种情况下,
x
的类型被推断为
int

多亏了@ildjarn,我找到了答案:

发件人:

静态解析的类型参数主要与成员约束结合使用,成员约束允许您指定类型参数必须具有特定成员才能使用。使用常规泛型类型参数无法创建此类约束

Visual Studio似乎应该给出不同的错误,例如: “此处不能使用成员约束,因为'T不是静态解析类型”或
“成员约束只能与静态解析的类型参数结合使用。”

多亏了@ildjarn,我找到了答案:

发件人:

静态解析的类型参数主要与成员约束结合使用,成员约束允许您指定类型参数必须具有特定成员才能使用。使用常规泛型类型参数无法创建此类约束

Visual Studio似乎应该给出不同的错误,例如: “此处不能使用成员约束,因为'T不是静态解析类型”或
“成员约束只能与静态解析的类型参数结合使用。”

这里有一个快速摘要,可能会有所帮助

您可以使用
内联
^T
以及成员约束为“具有此特殊API集的所有类型T”编写奇怪的代码;这是不能直接在.NET中编写的代码(例如,不能用C#编写),而且必须是
inline
,因为F#编译器可以在每个调用站点对特定类型进行内联/硬编码。这是一个非常高级的功能,因此您不太可能找到太多关于它的文档/示例(错误诊断并不总是很好)

您可以使用
'T
作为普通泛型,例如,您在C#中所做的常规泛型。这是一个主线场景

请注意,在这两种情况下,通常可以(/更好/更容易)让F#为您推断类型和泛型,而不是拼写出来。例如

let inline f x = float x

Visual Studio中的悬停提示显示已推断出适当的约束。

以下是一个快速摘要,可能会有所帮助

您可以使用
内联
^T
以及成员约束为“具有此特殊API集的所有类型T”编写奇怪的代码;这是不能直接在.NET中编写的代码(例如,不能用C#编写),而且必须是
inline
,因为F#编译器可以在每个调用站点对特定类型进行内联/硬编码。这是一个非常高级的功能,因此您不太可能找到太多关于它的文档/示例(错误诊断并不总是很好)

您可以使用
'T
作为普通泛型,例如,您在C#中所做的常规泛型。这是一个主线场景

请注意,在这两种情况下,通常可以(/更好/更容易)让F#为您推断类型和泛型,而不是拼写出来。例如

let inline f x = float x

Visual Studio中的悬停提示显示已推断出适当的约束。

@ildjarn,我已经能够使
内联的
或“静态解析的”参数类型以类似的方式工作,但在这个问题中,我在问标准运行时类型解析的正确语法。我不明白你的意思。如果没有
inline
,则无法使用静态解析的类型参数
float
需要静态解析的类型参数,因此任何要传递到
float
的函数都需要内联,除非您愿意将使用限制为单个类型。我想我不明白您所说的“float需要静态解析的类型参数”是什么意思。如果我将
x
约束为只有那些具有
op_Explicit:'T->float
的类型,那么在运行时还是编译时解析确切的类型又有什么关系呢?因为该约束(用F#术语)只能在编译时进行。:-]你可以使用反射来实现同样的效果,但是没有直接的语法,性能也会不太好。我明白你的意思了,我已经添加了一个总结的答案。@ildjarn,我已经能够让
内联的
或“静态解析的”参数类型以类似的方式工作,但是在这个问题中,我在问标准运行时类型解析的正确语法。我不明白你的意思。如果没有
inline
,则无法使用静态解析的类型参数
float
需要静态解析的类型参数,因此任何要传递到
float
的函数都需要内联,除非您愿意将使用限制为单个类型。我想我不明白您所说的“float需要静态解析的类型参数”是什么意思。如果我将
x
约束为只有那些具有
op_Explicit:'T->float
的类型,那么在运行时还是编译时解析确切的类型又有什么关系呢?因为该约束(用F#术语)只能在编译时进行。:-]你可以使用反射来实现同样的效果,但是没有直接的语法,而且性能也不太好。我明白你现在所说的,我已经为总结添加了一个答案。