2017-08-17 4 views
2

F#では、値が1回だけ割り当てられた識別された共用体を使用できますか?単一値の弁別された組合?

type DogAttributes = { Age: int; Color: string; } 

type Dog = 
| Rex of DogAttributes ({ Age = 5; Color = "Brown"; } 
| Fido of DogAttributes ({ Age = 3; Color = "White"; } 

Rexの値は常に割り当てられたDogAttributesを持ち、変更できませんでした。その時点で、あなただけでOOスタイルの多型を利用したほうが良いだろうように思える、

type DogAttribute = { Age : int; Color : string } 

type Dog = 
| Rex of DogAttribute 
| Fido of DogAttribute 

[<AbstractClass>] 
type DogBase(dog, age, color) = 
    member x.Age = age 
    member x.Color = color 
    member x.Dog = dog { Age = x.Age; Color = x.Color}  

type Rex() = 
    inherit DogBase(Dog.Rex, 5, "Brown")   

type Fido() = 
    inherit DogBase(Dog.Fido, 3, "White") 

をしかし:

+2

いいえ、それはできません。私は誰がどのようにそれを使いたいかもわかりません。 – TeaDrivenDev

+1

コンパイル時に、私が使いたい特定のDogの値をすべて知っていれば役に立ちます。明らかに、私はこのデータを他の場所に保存して見ることができます。これは私が今やっていることです。 –

+3

'Rex'と' Fido'は* types *のような気がしません、彼らは* values *のように感じます。あなたの問題のドメインをモデル化するより良い方法は 'let rex = DogAttributes {Age = 5;色= "ブラウン"} '。 – rmunn

答えて

2

@rmunnで指摘されているように、型を値と混同しているようです。 RexFidoは同じエンティティのインスタンスである必要があります。

type Dog = { Name: string; Age: int; Color: string } 

識別型共用体はここのいずれかの場所ではありませんが、それらは利点で列挙を考えることができます。あなたはもちろん、それらを組み合わせることができ

type Breed = 
| JackRussell 
| Labrador 
| Poodle 

...

type BadDog = 
| JackRussell of Dog 
| Labrador of Dog 
| Poodle of Dog 

let badJack = JackRussell({ Name = "Rex" ; Age = 5 ; Color = "brown" }) 

let badName = 
    match badJack with 
    | JackRussell(dog) 
    | Labrador(dog) 
    | Poodle(dog) 
     -> dog.Name 

は...しかし、指定されたコンテキストで、あなたはその後、望ましいよりマッチングやっていると思います。あなたがJackRussell代わりのBreed.JackRussell(あいまいさを解決する)使用していた可能性がBadDog型定義なし

type GoodDog = { Name: string; Age: int; Color: string; Breed: Breed } 
let goodJack = { Name = "Rex" ; Age = 5 ; Color = "brown" ; Breed = Breed.JackRussell } // (*) 

(*)。

より直接的な方法で犬の名前と照合したいと述べたコメントで。これを考慮するactive pattern

let (|DogName|) = function dog -> dog.Name 

match goodJack with 
| DogName "Rex" 
    -> printfn "Hello Rex" 
| _ -> printfn "Hello world" 
+1

アクティブパターンソリューションを示す良いアイデアです。 – rmunn

0

このコードは、あなたが望むものを達成でしょう。 差別化された組合だけで合計タイプを表現する唯一の方法ではありません。しかし、抽象クラスも同様に機能することができます。

証明:この回答に記載されているコード。

関連する問題