F#代码报价和通用功能

时间:2014-11-03 09:00:59

标签: generics f#

如果您尝试在< @@ @@> 符号之间附加泛型函数,请说

<@@ let f x = x in f 1 @@>

您收到以下编译错误:

  

引用的表达式中不允许使用内部泛型函数。考虑添加一些类型约束,直到此函数不再通用。

这是一个实施限制(尚未实现的缺失功能)还是概念问题(或两者兼而有之)?

编辑:只是为了澄清,即使使用符号&lt; @ @&gt; 的类型引用也会出现同样的错误。

编辑2:但是,您可以使用ReflectedDefinitionAttribute注释通用函数,其AST应该通过反射可用。

1 个答案:

答案 0 :(得分:3)

通用定义需要对API进行大量更改。例如,Quotation.Var类型有三个字段:名称,类型(由System.Type值表示)和可变性标志。但是如果你有通用定义,那么你需要扩展变量的Type属性以允许类型参数,而不仅仅是具体的.NET类型。但是代表这些有点棘手 - 你如何确保平等正常工作(例如在let z = let x (a:'a) = a in let y (a:'a) = a in x, y'a两个z: ('a->'a)*('b->'b)是独立的,不应该被视为相等,推断的签名是Quotation.Expr<int>

情况变得更糟。如果泛型类型是定义的内部类型(如示例所示),那么至少表达式的整体类型仍然可以在现有的F#类型系统中表示(例如,作为<@ fun x -> x @>)。但是如果类型变量可以&#34;逃避&#34;那么我们就会遇到一些棘手的问题。例如,Quotations.Expr<forall 'a.'a>的类型是什么?我们希望它类似于{{1}},但当然这在F#中不是有效类型。

并不是说解决这些问题是不可能,但这需要大量的设计,实施和测试工作,以及非平凡的变化到类型系统。