F# Asyncに関しての落書き その1
調べてる最中の落書きなので、指摘ある場合はどんどんお願いします。
コードを読むための前提知識(たぶん)
- .NETの非同期
- 継続
- Trampoline
ソースコード
今読んでるやつ
FakeUnitValue
ここはコメントの通り、と。
Trampoline
内部でのAsync専用Trampolineの実装に.NETの限界を垣間見る
do!とか
Async in C# and F#: Asynchronous gotchas in C# (Japanese translation) に"末尾再帰関数では do!
より return!
を使うべき"とか書いてあった気がする。do!
の変換を見てみよう。
上記でも解説されている通り、do!
には二つの変換パターンが存在する。
T(do! e in ce, C) = T(let! () = e in ce, C) T(do! e;, C) = T(let! () = src(e) in b.Return(), C)
末尾再帰関数として使う場合に使うのは後者。Bindが適用されてからReturnする影響でリークする可能性があるのかな?(実装を全部読む時間が足りない…)まぁ、無駄な呼び出しはしないほうが良いのは確かだ。
Asyncとは関係ないが、let!
でもSource適用するのになんでdo!にもつけたのだろう。それも片方の変換だけ…
Async.Catch
コンピュテーション式内でtry withを使うのとAsync.Catchで包むの、どちらが良いのだろう?え、Choice使いたくない?まぁ、はい。
overload
テストで思い切りビルダーに対して拡張メソッドを定義している…わりとよくやるのだろうか。というか、F# 3.0以降なら
type Microsoft.FSharp.Control.AsyncBuilder with member x.Source(computation:Task<'T>) = Async.AwaitTask computation
でいいのでは感。どうせなら次のバージョンで標準搭載されてほしい。
会社に遅刻するので、今日はここまで。