2017-03-23 17 views
3

Fシャープレコードの新しいプロパティを変更して追加する必要があります。しかし、この新しいフィールドがなくても前のインスタンスにエラーが発生します。私はNullableとして作成しましたが、同じエラーが発生しました。この問題を解決するのを手伝ってください。Fsharpレコードのオプションパラメータ

+1

この質問はあいまいですが、答えは 'with'キーワード –

+0

Qにいくつかのコードを追加できますか? –

+1

前のインスタンスが新しいフィールドを使用するように更新しますか? –

答えて

7

「レコードをインスタンス化するときに提供していないフィールド」のように「オプション」を意味します。しかし、残念なことにF#レコードのオプションフィールド(またはあなたの視点に応じて、幸運なことに)のようなものはありません。指定したすべてのレコードフィールドは、インスタンス化する時点ででなければなりません。

this closely related questionも参照してください。

  • 記録を使用してください:あなたはこのトレードオフを考慮することができる

    。レコードを更新するたびに、F#コンパイラはこのレコードを使用したすべての場所について叫んで警告し、追加情報を提供する必要があります。オプションの場合、追加したフィールドの追加情報はNoneになります。大きな利点:field1が見つからない場合はどうすればよいでしょうか?field2も見つからない場合はどうなりますか?

  • クラスを使用してください。クラスを更新すると、F#コンパイラは、クラスに入れた情報に関する完全性チェックを実行しません。 (レコードは、すべてのフィールドがコンストラクタ引数であり、すべてが提供されなければならないクラスとしてレコードを見ることができます)。したがって、クラス定義を更新するとオーバーヘッドは発生しませんが、コードですべての欠損値を処理する必要があります。

私は新しいフィールドを追加することの意味合いを通じて考えるようにそれので、私は個人的にレコードを好みます。

はもちろん、ミドルグラウンドがあります:あなたは、レコードを使用しますが、静的メンバまたは同様のものを経由して、それらのすべてのインスタンスを作成することができます

type Name = 
    { 
     First: string 
     Family: string 
    }   
    static member Create(first, family) = { First = first; Family = family} 

場合は、あなたのコードでは、あなたはいつもレコードをインスタンス化するName.Createを使用しますもちろん、消費者コードに気づかずにMiddleNameフィールドを追加することもできます。

5

「初期化されていない変数」が機能的な考え方に存在しないという単純な理由から、Option typeがF#でnullよりも優先されます。

最初に、ボスによって承認されなければならないVacationRequestを表すレコードを作成しましょう。

type VacationRequest = 
    {Name : string 
    Date : DateTime 
    Approval : string option} 

あなたのアプローチの問題点は、すべてのフィールドが建設に割り当てなければならないことであるので、これはコンパイルされません。

let holiday = 
    {Name = "Funk" 
    Date = DateTime(2020,12,31)} 

あなたは暗黙的に設定し、ヘルパー関数を使用して、この問題を回避することができますオプション値

let fillInRequest name date = 
    {Name = name 
    Date = date 
    Approval = None} 

これで、ヘルパー機能を使用してレコードを作成できます。

let holiday = fillInRequest "Funk" <| DateTime(2020,12,31) 

FSIにコードを送信するときに面白いことに気付いた。

val holiday : VacationRequest = {Name = "Funk"; 
           Date = 31/12/2020 12:00:00 ; 
           Approval = null;} 

上司はその要求(新しいレコードを作成する)

let approvedHoliday = 
    {holiday with Approval = Some "boss' name"} 
val approvedHoliday : VacationRequest = {Name = "Funk"; 
             Date = 31/12/2020 12:00:00 ; 
             Approval = Some "boss' name";} 

または

変更せずにそれを送り返すを更新でき0
let betterLuckNextTime = holiday 
関連する問題