代码引用中的F#数字文字

时间:2012-09-18 07:41:58

标签: f#

我想在代码引用中使用数字文字。

遵循两个贡献

Function templates in F#

How to write a function for generic numbers?

一种方法是:

type FromInt = FromInt with
    static member ($) (FromInt, _:sbyte     ) = fun (x:int) -> sbyte      x
    static member ($) (FromInt, _:int16     ) = fun (x:int) -> int16      x
    static member ($) (FromInt, _:int32     ) = id
    static member ($) (FromInt, _:float     ) = fun (x:int) -> float      x
    static member ($) (FromInt, _:float32   ) = fun (x:int) -> float32    x
    static member ($) (FromInt, _:int64     ) = fun (x:int) -> int64      x
    static member ($) (FromInt, _:nativeint ) = fun (x:int) -> nativeint  x
    static member ($) (FromInt, _:byte      ) = fun (x:int) -> byte       x
    static member ($) (FromInt, _:uint16    ) = fun (x:int) -> uint16     x
    static member ($) (FromInt, _:char      ) = fun (x:int) -> char       x
    static member ($) (FromInt, _:uint32    ) = fun (x:int) -> uint32     x
    static member ($) (FromInt, _:uint64    ) = fun (x:int) -> uint64     x
    static member ($) (FromInt, _:unativeint) = fun (x:int) -> unativeint x
    static member ($) (FromInt, _:bigint    ) = fun (x:int) -> bigint     x
    static member ($) (FromInt, _:decimal   ) = fun (x:int) -> decimal    x
    static member ($) (FromInt, _:Complex   ) = fun (x:int) -> Complex(float x,0.0)  

let inline fromInt (a:int) : ^t = (FromInt $ Unchecked.defaultof< ^t>) a

module NumericLiteralG =
    [<ReflectedDefinition>]
    let inline FromZero() = LanguagePrimitives.GenericZero
    [<ReflectedDefinition>]
    let inline FromOne() = LanguagePrimitives.GenericOne
    [<ReflectedDefinition>]
    let inline FromInt32 (i:int) = fromInt i

添加[&lt; ReflectedDefinition&gt; ]每个($)运算符的属性都没问题。但 一旦我添加[&lt; ReflectedDefinition&gt; ]到

let inline fromInt (a:int) : ^t = (FromInt $ Unchecked.defaultof< ^t>) a

我收到以下编译错误:

“引号不能包含进行成员约束调用的表达式,也不能使用隐式解析为成员约束调用的运算符”

这是报价的限制吗?是否有另一种方法可以获得相同的效果?

非常感谢任何想法。

1 个答案:

答案 0 :(得分:4)

报价在很多方面受到限制。例如,它们不能包含泛型函数,这意味着以下内容不起作用:

<@ let id a = a in (id 3, id "A") @>

他们无法处理像fromInt函数这样的静态成员约束的函数,这不足为奇。

但是,我不太明白为什么你希望能够获得fromInt的引用?

  • 通常,引用用于获取某些F#代码的AST并将其转换为其他形式(如SQL查询,JavaScript或GPU代码)。这意味着您将编写一些递归遍历AST的函数,转换代码并以某种特殊方式处理基元。

如果您未将fromInt标记为inlineReflectedDefinition,则可以将此单个函数作为基元处理。 (另一方面,如果内联,则必须处理FromInt.($)运算符。

  • 或者,您可能正在转换引号然后编译它,但在这种情况下,您应该只能编译包含对fromInt的调用的引用代码...

所以,我很好奇你想看到fromInt的引用是什么原因?