コンピュテーション式の壊れた部分がなおりそう

F# Advent Calendar 2020の6日目のエントリーです。

今日は将来のF#の話です。

RFC FS-1087

RFC FS-1087は3つのFeatureをまとめたRFCとなっています。

  • Tasks
  • Resumable state machines
  • Respecting Zero methods in computation expressions

ひとつめはコンピュテーション式で Task が扱えるビルダーを追加しましょうという話です。 これは特に面白みはありません。

ふたつめはF# vNextは何が "ヤバい" のか: Monadic Programming の新時代という素晴らしいエントリーで言及されている話で、 とてもワクワクする話ですが、今回はこれの話ではありません。

みっつめの「Respecting Zero methods in computation expressions」についてです。

Respecting Zero methods in computation expressions

これは4年前に書いたComputation Expression Problemの解決です。

RFCではこうあります。

このRFC以前では、 do! expr がコンピュテーション式の最後の位置にある場合、次のように処理された。

  1. Return メソッドがある場合、 builder.Bind(expr, fun () -> builder.Return())
  2. そうでない場合、 builder.Bind(expr, fun () -> builder.Zero())

新しいルールは追加の条件を持ち、次のようになる。

  1. Return メソッドがあり、DefaultValue 属性が付いた Zero メソッドがない場合、 builder.Bind(expr, fun () -> builder.Return())
  2. そうでない場合、 builder.Bind(expr, fun () -> builder.Zero())

つまり、 DefaultValue 属性付きの Zero メソッドがある場合、今までは Return に変換されていたのが Zero に変換されるようになるわけです。

DefaultValue 属性を使わない場合は既存の挙動と同じになるというのはうまい回避方法だと思います。

これによって、より使いやすいコンピュテーション式ビルダーが提供できるようになるでしょう。 将来の楽しみが増えますね!