6

判別共用体の特定のメンバーをパラメーターの型として使用しようとしています。例えば:

type SomeUnion =
   | A of int * int
   | B of string

type SomeType(A(i, j)) =
    member this.I = i
    member this.J = j

let a = A(10, 20)
let instance = SomeType(a)

しかし、これは不正な構文であり、SomeType の param リストに対して「Unexpected symbol '(' in type definition」というエラーが表示されます。これは有効な構文です。

let doSomethingWithA (A(i, j)) = i + j

しかし、型シグネチャはSomeUnion -> intではなく でありA -> int、不完全なパターン一致について不平を言っています (シグネチャを考えると理解できます)。

それで、これは可能ですか?F# のユニオン メンバーは CLR クラスにコンパイルされるので、理論的には可能と思われますが、実際には (つまり、リフレクションのようなものを使用せずに) 可能でしょうか? それ以外の場合は、より冗長な手動の OOP 方法を実行する必要があり、完全な一致を保証できないと思います。

4

3 に答える 3

7

コンストラクターの引数をパターン マッチできないのは驚くべきことだと思います。通常のメンバーでも機能します。

値が間違っている場合に実行時エラーを取得するために、コンストラクターで明示的な一致を行うことができます。

type SomeType(a) =
    let i, j = match a with | A(k, l) -> k, l
    member this.I = i
    member this.J = j

しかしそうでなければ、それは型でAないことを理解する必要があります。したがって、 の型が期待どおりでなくても驚くことではありdoSomethingWithAません。そして、不完全なパターン マッチの警告に対処する必要があります。

于 2013-01-14T15:49:53.373 に答える
6

wmeyer が指摘しているように、DU の「A」ケースはまったくタイプではなく、単なる共用体タイプのコンポーネントです。

ユニオン ケースの 1 つを単独で本当に再利用したい場合は、それを明示的なスタンドアロン型にする以外に方法はありません。

オプション 1 は、タイプ エイリアスを使用することです。

type TypeA = int * int

type SomeUnion =
    | A of TypeA 
    | B of string

type SomeType(a:TypeA) =
    let (i,j) = a
    member this.I = i
    member this.J = j

let a = (10, 20)
let instance = SomeType(a)

TypeAわかりやすくするために、コンストラクターに注釈を追加しました。

2 番目のオプションは、単一ケースの DU にラップすることです。

type TypeA = TA of int * int

type SomeUnion =
    | A of TypeA 
    | B of string

type SomeType(a:TypeA) =
    let (TA(i,j)) = a  
    member this.I = i
    member this.J = j

let a = TA (10, 20)
let instance = SomeType(a)

let (TA(i,j)) = a(関数と混同しないように、一致には余分な括弧が必要であることに注意してください。)

于 2013-01-14T21:24:06.730 に答える
5

私の F# は少し錆びていますが、このようなことができるでしょうか (モノラルで f# 2 でテスト済み)。

type SomeUnion =
   | A of int * int
   | B of string

type SomeType(i:int, j:int) =
    member this.I = i
    member this.J = j

let createSomeType(SomeUnion.A(i,j)) = new SomeType(i,j)
let a = A(10, 20)
let instance = createSomeType(a)
于 2013-01-14T13:53:49.250 に答える