首页 文章

简单的F#运行时泛型函数与类型约束无法解析

提问于
浏览
2

我有一个基本功能,有一个通用参数:

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

为什么我收到错误:“由于在编译时无法解析类型参数,因此无法使用声明的类型参数'T

在这个例子中,我已经阅读了所有与F#中的泛型相关的MSDN文档,但它们似乎只是在圈内,并不符合我在Visual Studio中看到的行为 . 根据我的理解,使用单引号语法 'T 用于运行时泛型,而不是编译时泛型 .

这让我想到另一个问题 . 我经常看到语法 'T^T 混合,有和没有 inline . 这违反了有关这些语法定义的MSDN文档 . 我错过了什么吗?

此外,从文档中,似乎应该能够自动推断类型 'T 上的 op_Explicit 约束,而不需要任何类型注释:

let func x =
   float x

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

2 回答

  • 4

    这是一个可能有用的快速摘要 .

    您使用 inline^T 以及成员约束来编写奇怪的代码'for all types T that have this ad-hoc API set';这是无法直接在.NET中编写的代码(例如,您无法在C#中编写),并且它必须是 inline ,因为F#编译器可以在每个单独的调用站点内联/硬编码特定类型 . 这是一个非常高级的功能,因此您不太可能找到太多关于它的文档/示例(并且错误诊断并不总是很好) .

    您将 'T 用于普通泛型,例如你在C#中常用的通用东西 . 这是主线情景 .

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

    let inline f x = float x
    

    Visual Studio中的悬停提示超过 f 表明已推断出适当的约束 .

  • 0

    感谢@ildjarn,我找到了答案:

    来自http://msdn.microsoft.com/en-us/library/dd548046

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

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

相关问题