2

null をサポートする構造体または参照型のいずれかに型を制約することは可能ですか? この関数に対する仮説上の制約のようなもの:

let getOrDefault<'T when ('T : struct) or ('T : null)> (d: IDictionary<_, 'T>) key =
  match d.TryGetValue(key) with
  | true, v -> v
  | _ -> Unchecked.defaultof<'T>

でマークされていない限り、関数は F# 型で使用しないでください[<AllowNullLiteral>]

4

1 に答える 1

3

or2 つの制約の間に挟むことはできないと思います。通常、constraint1、constraint2、...、constraintN のようなものが必要な場合は、オーバーロードを作成します。

open System.Collections.Generic

// unconstrained function
let getOrDefaultG (d: IDictionary< _ , 'T>) key =
  match d.TryGetValue(key) with
  | true, v -> v
  | _ -> Unchecked.defaultof<'T>

// individually constrained
let getOrDefaultS<'K,'T when 'T :struct> (d:IDictionary<'K,'T>) = getOrDefaultG d
let getOrDefaultN<'K,'T when 'T :null  > (d:IDictionary<'K,'T>) = getOrDefaultG d

// overloads
type GetOrDefault = GetOrDefault with
    static member ($) (GetOrDefault, d) = fun dummyArg        -> getOrDefaultS d
    static member ($) (GetOrDefault, d) = fun (dummyArg:unit) -> getOrDefaultN d

// the desired function
let inline getOrDefault d key = (GetOrDefault $ d) () key

注: dummyArg は、2 つの異なる署名を作成してコンパイルするために使用するトリックです。

于 2012-08-07T06:11:00.420 に答える