静的に解決される型パラメーターStatically Resolved Type Parameters

A静的に解決される型パラメーター型パラメーターでは、実行時ではなく、コンパイル時に実際の型に置き換えられます。A statically resolved type parameter is a type parameter that is replaced with an actual type at compile time instead of at run time. これらの前にはキャレット (^) 記号が付きます。They are preceded by a caret (^) symbol.

構文Syntax

ˆtype-parameter

RemarksRemarks

F# 言語には、異なる 2 種類の型パラメーターがあります。In the F# language, there are two distinct kinds of type parameters. 1 つ目の種類は、標準のジェネリック型パラメーターです。The first kind is the standard generic type parameter. これらは、'T'U のようにアポストロフィ (') で示されます。These are indicated by an apostrophe ('), as in 'T and 'U. これらは、他の .NET Framework 言語のジェネリック型パラメーターと同じです。They are equivalent to generic type parameters in other .NET Framework languages. もう 1 つの種類は、静的に解決される型パラメーターであり、^T^U のようにキャレット記号で示されます。The other kind is statically resolved and is indicated by a caret symbol, as in ^T and ^U.

静的に解決される型パラメーターは、主にメンバー制約で使用する場合に役立ちます。これは、型引数を使用するために特定のメンバーが必要であることを指定できる制約です。Statically resolved type parameters are primarily useful in conjunction with member constraints, which are constraints that allow you to specify that a type argument must have a particular member or members in order to be used. この種の制約を、標準のジェネリック型パラメーターを使用して作成する方法はありません。There is no way to create this kind of constraint by using a regular generic type parameter.

2 種類の型パラメーターの類似点と相違点の概要を次の表に示します。The following table summarizes the similarities and differences between the two kinds of type parameters.

機能Feature ジェネリックGeneric 静的に解決されるStatically resolved
構文Syntax 'T, 'U'T, 'U ^T, ^U^T, ^U
解決時期Resolution time 実行時Run time コンパイル時Compile time
メンバー制約Member constraints メンバー制約では使用できません。Cannot be used with member constraints. メンバー制約で使用できます。Can be used with member constraints.
コード生成Code generation 標準のジェネリック型パラメーターを持つ型 (またはメソッド) では、単一のジェネリック型またはジェネリック メソッドが生成されます。A type (or method) with standard generic type parameters results in the generation of a single generic type or method. 各型で必要とされる、型およびメソッドの複数のインスタンス化が生成されます。Multiple instantiations of types and methods are generated, one for each type that is needed.
型での使用Use with types 型で使用できます。Can be used on types. 型では使用できません。Cannot be used on types.
インライン関数での使用Use with inline functions いいえ。No. 標準のジェネリック型パラメーターではインライン関数をパラメーター化できません。An inline function cannot be parameterized with a standard generic type parameter. はい。Yes. 静的に解決される型パラメーターは、インライン以外の関数またはメソッドでは使用できません。Statically resolved type parameters cannot be used on functions or methods that are not inline.

多数の F# コア ライブラリ関数 (特に演算子) には、静的に解決される型パラメーターがあります。Many F# core library functions, especially operators, have statically resolved type parameters. これらの関数および演算子はインラインであり、数値の計算に効率的なコードが生成されます。These functions and operators are inline, and result in efficient code generation for numeric computations.

演算子を使用するインライン メソッドおよび関数、または静的に解決される型パラメーターを持つ他の関数を使用するインライン メソッドおよび関数では、それらのメソッドおよび関数自体でも静的に解決される型パラメーターを使用できます。Inline methods and functions that use operators, or use other functions that have statically resolved type parameters, can also use statically resolved type parameters themselves. 多くの場合、型推論では、それらのインライン関数が静的に解決される型パラメーターを持つと推論されます。Often, type inference infers such inline functions to have statically resolved type parameters. 静的に解決される型パラメーターを持つと推論される演算子の定義を次の例に示します。The following example illustrates an operator definition that is inferred to have a statically resolved type parameter.

let inline (+@) x y = x + x * y
// Call that uses int.
printfn "%d" (1 +@ 1)
// Call that uses float.
printfn "%f" (1.0 +@ 0.5)

解決された (+@) の型は、(+) および (*) の使用に基づいており、これらの両方では型推論によって、静的に解決される型パラメーターによるメンバー制約が推論されます。The resolved type of (+@) is based on the use of both (+) and (*), both of which cause type inference to infer member constraints on the statically resolved type parameters. F# インタープリターに表示される解決された型は、次のとおりです。The resolved type, as shown in the F# interpreter, is as follows.

^a -> ^c -> ^d
when (^a or ^b) : (static member ( + ) : ^a * ^b -> ^d) and
(^a or ^c) : (static member ( * ) : ^a * ^c -> ^b)

出力は次のとおりです。The output is as follows.

2
1.500000

以降でF#4.1、静的に解決される型のパラメーター シグネチャで具体的な型名を指定することもできます。Starting with F# 4.1, you can also specify concrete type names in statically resolved type parameter signatures. 言語の以前のバージョンでは、型名は、実際には、コンパイラによって推論でしたが、署名では実際には指定できません。In previous versions of the language, the type name could actually be inferred by the compiler, but could not actually be specified in the signature. F# 4.1、静的に解決される型のパラメーター シグネチャで具体的な型名を指定することも可能性があります。As of F# 4.1, you may also specify concrete type names in statically resolved type parameter signatures. 次に例を示します。Here's an example:

let inline konst x _ = x

type CFunctor() = 
    static member inline fmap (f: ^a -> ^b, a: ^a list) = List.map f a
    static member inline fmap (f: ^a -> ^b, a: ^a option) =
        match a with
        | None -> None
        | Some x -> Some (f x)

    // default implementation of replace
    static member inline replace< ^a, ^b, ^c, ^d, ^e when ^a :> CFunctor and (^a or ^d): (static member fmap: (^b -> ^c) * ^d -> ^e) > (a, f) =
        ((^a or ^d) : (static member fmap : (^b -> ^c) * ^d -> ^e) (konst a, f))

    // call overridden replace if present
    static member inline replace< ^a, ^b, ^c when ^b: (static member replace: ^a * ^b -> ^c)>(a: ^a, f: ^b) =
        (^b : (static member replace: ^a * ^b -> ^c) (a, f))

let inline replace_instance< ^a, ^b, ^c, ^d when (^a or ^c): (static member replace: ^b * ^c -> ^d)> (a: ^b, f: ^c) =
        ((^a or ^c): (static member replace: ^b * ^c -> ^d) (a, f))

// Note the concrete type 'CFunctor' specified in the signature
let inline replace (a: ^a) (f: ^b): ^a0 when (CFunctor or  ^b): (static member replace: ^a *  ^b ->  ^a0) =
    replace_instance<CFunctor, _, _, _> (a, f)

関連項目See also