如果您尝试在< @@ 和 @@> 符号之间附加泛型函数,请说
<@@ let f x = x in f 1 @@>
您收到以下编译错误:
引用的表达式中不允许使用内部泛型函数。考虑添加一些类型约束,直到此函数不再通用。
这是一个实施限制(尚未实现的缺失功能)还是概念问题(或两者兼而有之)?
编辑:只是为了澄清,即使使用符号&lt; @ 和 @&gt; 的类型引用也会出现同样的错误。
编辑2:但是,您可以使用ReflectedDefinitionAttribute
注释通用函数,其AST应该通过反射可用。
答案 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#中不是有效类型。
并不是说解决这些问题是不可能,但这需要大量的设计,实施和测试工作,以及非平凡的变化到类型系统。