2016-01-13 4 views
6

F#では、クラスを定義せずに制限付きの型を表すことはできますか? 最初の分割数を2番目の分割数のすべての対として表現したいとします。私は何ができるC#でクラスを使用しない制限された型の表現

class PairDivides 
{ 
    int a {get;private set;} 
    int b {get;private set;} 

    PairDivides(int first, int second) 
    { 
     if (a % b != 0) 
     { 
      throw new Exception(); 
     } 

     this.a = first; 
     this.b = second; 
    } 
} 

は、今ではbaを分割しないPairDividesインスタンスを作成することは不可能です...これだけの機能構築物を用いてF#で

を行うことができます(記録、差別化された組合、おそらくアクティブなパターンなど)?

私は、これらのペアが正しく構築されていることを確認して、何かを受信したいと思っています。

+0

は静的メンバ –

+0

またはそのような何かを追加することができint型。 b:int} try create a b = if a%b = 0ならば{a = a; b = b} |>他の何もなしhttps://dotnetfiddle.net/veMXnx –

+0

確かに...壊れたペアを作成することは不可能でなければなりません。 –

答えて

6

これを行うには、タイプをprivateにします。ペアを作成する機能を提供することにより

module Pairs = 
    type PairDivides = private { a: int; b: int } 

    let createPairDivides a b = 
     match a % b with 
     | 0 -> Some { PairDivides.a = a ; b = b } 
     | _ -> None 

    let print div = 
     printfn "{%d %d}" div.a div.b 

    let tryPrint div = 
     match div with 
     | Some a -> print a 
     | None -> printfn "None" 

let a = Pairs.createPairDivides 2 2 

let b = a.Value 

// This is inaccessible: b.a 

Pairs.createPairDivides 2 2 |> Pairs.tryPrint 
Pairs.createPairDivides 2 3 |> Pairs.tryPrint 

、および必要に応じて使用するか、またはそれから抽出する機能を、あなたは完全に作成する機能を排除:唯一の欠点は、あなたがデータにアクセスするための機能を提供する必要があるということです無効なペア(悪いペアの代わりにNoneを返す)例外を使用しない

不利な点は、現在のモジュールの外部で使用するとタイプにアクセスできないため、ペアから値を抽出するメカニズムを提供する必要があることです。

言われていることは、クラスを介してこれを行うことにも問題はありません。ご希望の場合は、クラスを作成を通じて執行の同じレベルを得ることができますタイプPairDivides = {::

type PairDivides private (a,b) = 
    member __.A = a 
    member __.B = b 

    static member Create a b = 
     match a % b with 
     | 0 -> Some(PairDivides(a,b)) 
     | _ -> None 


PairDivides.Create 2 2 |> printfn "%A" 
PairDivides.Create 2 3 |> printfn "%A" 
+0

良い答え。しかし、実際には2つのコンセプトを組み合わせて、一対のプロパティをレコードタイプに直接割り当てることができると思います。これは、最初の例のように、作成ロジックと他の関数をモジュールに入れても、 'A'と' B'を公開することになります。 – TheInnerLight

関連する問題