什么时候在F#中支持无类型的打字报价?

soc*_*soc 9 f# types programming-languages metaprogramming quotations

F#有类型和无类型的代码引用,我想知道哪个用户会选择一个而不是另一个?

区别只是方便和无类型和类型化的引用在所有情况下都可以转换为每种情况,或者是类型化的引用,例如可能使用无类型引用的子集?

有没有任何例子只适用于打字,但没有使用无类型报价 - 或者相反?

kvb*_*kvb 7

一般来说,我建议你尽可能使用打字报价.像往常一样,这些类型将允许您静态地强制执行某些可能导致运行时失败的正确性条件.考虑:

let one = <@@ "one" @@>
// exception at runtime
let two = <@@ 1 + %%one @@>
Run Code Online (Sandbox Code Playgroud)

而不是

let one = <@ "one" @>
// compile time error: the type 'string' does not match the type 'int'
let two = <@ 1 + %one @>
Run Code Online (Sandbox Code Playgroud)

此外,有时无类型引用在类型引用不包含的情况下需要额外的类型注释:

// ok
let l = <@ [1] @>
let l2 = <@ List.map id %l @>

// fails at runtime (obj list assumed instead of int list)
let l = <@@ [1] @@>
let l2 = <@@ List.map id %%l @@>

// ok
let l = <@@ [1] @@>
let l2 = <@@ List.map (id:int->int) %%l @@>
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在构建非常通用的引用内容,则可能无法使用类型化引用(例如,因为类型不是静态知道的).从这个意义上说,无类型引用会给你更多的灵活性.

另请注意,根据需要在类型化和非类型化引用之间进行转换非常容易(向上Expr<_>转换Expr为从键入到无类型;用于Expr.Cast转向另一种方式).