【问题标题】:F# Code Quotations and generic functionsF# 代码引用和泛型函数
【发布时间】:2014-11-04 04:24:36
【问题描述】:

如果你尝试在 @@> 符号之间包含一个通用函数,比如说

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

你得到以下编译错误:

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

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

编辑:为了澄清起见,即使使用符号 @> 键入引号也会发生相同的错误。

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

【问题讨论】:

  • 有效吗? --> 分隔键入的代码引号。
  • 不,你会得到同样的错误。
  • 这只是一个例子吗?如果不是错误说明了一切 - 您可能不会使用内部函数来生成 <@@ let f (x : int) = x in f 1 @@>
  • @Carsten König。我对此很清楚。谢谢。但是,我很想知道问题是否在于引用是如何实现的(即微软没有为通用函数实现引用),或者在概念上是不可能做到的。那么限制是关于引用的实现还是引用的概念?
  • 如果你在某个会议上遇到了 Don,那么我肯定没有资格回答 任何问题 ;) - 我猜它使用 Expressing&lt;Func&lt;...&gt;&gt;内部函数,这当然不适用于泛型参数

标签: generics f#


【解决方案1】:

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

而且情况会变得更糟。如果泛型类型在定义内部(如您的示例中),那么至少表达式的整体类型仍然可以在现有的 F# 类型系统中表示(例如,作为Quotation.Expr&lt;int&gt;)。但是如果类型变量可以“逃逸”,那么我们就有了一些棘手的问题。比如&lt;@ fun x -&gt; x @&gt;的类型是什么?我们希望它类似于 Quotations.Expr&lt;forall 'a.'a&gt;,但在今天的 F# 中这当然不是一个有效的类型。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多