ネストしたレコードの更新が楽になるかも?
F# Advent Calendar 2020の9日目のエントリーです。
今日は(も?)、入ると嬉しいRFCの話です。
RFC FS-1049
RFC FS-1049は、
ネストしたレコードのフィールドを with
で書き換えられるように拡張しよう、というものです*1。
F#のレコードは with
を使うことで、一部のフィールドのみを更新した新しいレコードが作れます。
type Customer = { Name: string Address: string Age: int } // NameとAddressはそのままにAgeをインクリメントする関数 let incrAge customer = { customer with Age = customer.Age + 1 }
しかし、ネストしたレコードを更新するためには with
もネストして使う必要があります。
例えば、
type A = { X: B } and B = { Y: C } and C = { Z: string } let a = { X = { Y = { Z = "str" } } }
こういうレコードがあった場合に Z
を更新するには、
let a' = { a with X = { a.X with Y = { a.X.Y with Z = "updated" } } }
のようにしなければなりません。
RFC FS-1049は、こう書けるようにしようという提案です。
let a' = { a with X.Y.Z = "updated" }
とてもシンプルになりましたね。
ただこれ、フィールドが option
とかだとおそらく結局ネストが必要です。
type A = { X: B } and B = { Y: C option } and C = { Z: string } let a = { X = { Y = Some { Z = "str" } } } let a' = { a with X.Y = a.X.Y.map(fun y -> { y with Z = "updated" }) }
まぁ、以前より便利になることは確実なので、入ってほしい拡張ではありますね。
*1:もともとの提案は、「ファーストクラスのLens入れようぜ!」というものだったので大分おとなしいところに着地した感はあります。