1

I want to use numeric literals in code quotations.

Following the two contributions

Function templates in F#

How to write a function for generic numbers?

one approach is:

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

Adding [ < ReflectedDefinition > ] attribute to each of the ($) operators is fine. But once I add [ < ReflectedDefinition > ] to

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

I get the following compile error:

"Quotations cannot contain expressions that make member constraint calls, or uses of operators that implicitly resolve to a member constraint call"

Is this a limitation of quotations? Is there an alternative approach to get the same?

Many thanks for any idea.

4

1 に答える 1

4

引用は多くの点で制限されています。たとえば、汎用関数を含めることはできません。つまり、次の関数は機能しません。

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

関数のような静的メンバー制約を持つ関数を処理できないことは驚くべきことではありませんfromInt

fromIntしかし、なぜあなたが?の見積もりを取得できるようにしたいのか、私にはよくわかりません。

  • 通常、引用符は、F# コードの AST を取得し、それを他の形式 (SQL クエリ、JavaScript、GPU コードなど) に変換するために使用されます。これは、AST を再帰的に走査し、コードを変換し、プリミティブを特別な方法で処理する関数を作成することを意味します。

fromIntとしてマークinlineしない場合はReflectedDefinition、この単一の関数をプリミティブとして処理できます。(一方、インライン化されている場合は、FromInt.($)演算子を処理する必要があります。

  • fromIntまたは、引用を変換してからコンパイルすることもできますが、この場合、 ...への呼び出しを含む引用されたコードをコンパイルできるはずです。

では、なぜあなたが の引用を見たいと思ったのか知りたいfromIntです。

于 2012-09-18T13:45:03.710 に答える