2

次のコードを検討してください...

type TypeOne () =
    member val Name = "" with get, set

type TypeTwo () =
    member val Name = "" with get, set
    member val Property = 0 with get, set

[<RequireQualifiedAccess>]
type UnionType =
    | TypeOne of TypeOne
    | TypeTwo of TypeTwo

// this only succeeds because we have defined the union type a
// requiring qualified access. otherwise TypeOne would be inferred
// as the union case, not the type (understandably)...

let t1 = TypeOne ()

// if we want t1 "as" the union type, we have to do the following...

let ut1 = UnionType.TypeOne t1

// the following function returns a result of type UnionType
// but we have to explicitly do this for each type

let makeUnion switch =
    match switch with
        | true -> UnionType.TypeOne (TypeOne ())
        | _ -> UnionType.TypeTwo (TypeTwo ())

コメントのように、戻り結果が共用体タイプである必要があると推測する方法はないようです。共用体タイプで修飾されたアクセスを要求する必要がある場合、これは非常に冗長です(これは心配そうに間違っているようです)。

また、共用体型のみを受け取り、それらを共用体として返す関数を作成する方法もありません。(この場合、TypeOneまたはTypeTwoを受け取り、UnionTypeを返す関数)。それともありますか?差別化された組合と協力するためのより良い方法はありますか?

4

2 に答える 2

2
type TypeOne() =
    member val Name = "" with get, set

type TypeTwo() =
    member val Name = "" with get, set
    member val Property = 0 with get, set

type UnionType =
    | TypeOne of TypeOne
    | TypeTwo of TypeTwo

/// You can give some hints to the type checker 
/// by saying that you want a class constructor
let t1 = new TypeOne()

/// No need to use fully-qualified access on union types
let ut1 = TypeOne t1

let makeUnion switch =
    match switch with
    | true -> TypeOne (new TypeOne())
    | false -> TypeTwo (new TypeTwo())
于 2012-12-17T10:19:09.103 に答える
2

padが指摘しているように、ユニオンケースをその親タイプで修飾する必要はないので、次のように記述できます。

let makeUnion switch =
    match switch with
    | true -> TypeOne (new TypeOne ())
    | false -> TypeTwo (new TypeTwo ())

ただし、常にを指定する必要がありますTypeOne。これは、同じ引数を取る複数のケースがある場合に存在するあいまいさを回避するためです-のように

type foo=
|Bar of int
|Baz of int

そうすると、戻り型を知っていても、コンパイラは何を返すかを判断できません。より一般的な例は、実際には引数をとらない場合です。たとえば、trueとfalseを再定義することにしたとします。

type bool = |True |False
于 2012-12-17T10:30:39.260 に答える