1

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

在两个贡献之后

F# 中的函数模板

如何为通用数字编写函数?

一种方法是:

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

为每个 ($) 运算符添加 [ < ReflectedDefinition > ] 属性就可以了。但是一旦我将 [ < ReflectedDefinition > ] 添加到

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

我收到以下编译错误:

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

这是报价的限制吗?有没有其他方法可以得到相同的结果?

非常感谢您的任何想法。

4

1 回答 1

4

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

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

他们不能像你的fromInt函数那样处理具有静态成员约束的函数,这不足为奇。

但是,我不太明白您为什么希望能够获得fromInt?

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

如果你不标记fromIntinline然后ReflectedDefinition你可以只处理这个单一的功能作为一个原语。(另一方面,如果它是内联的,则必须处理FromInt.($)运算符。

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

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

于 2012-09-18T13:45:03.710 回答