エフェクトの文書化
from Modeling Workflows as Pipelines
LT;DR
エフェクトを用いて、関数が主な出力以外に行うことを説明する
関数のシグネチャでエフェクトを文書化する
エラーが起こり得るケース: Result
I/O 処理を行うケース: Await
hr.icon
型を使ったワークフローの各ステップのモデリング の各ステップの エフェクト を考える
関数のシグネチャでエフェクトを文書化する
エラーを返すか?(Result エフェクト)
I/O 処理をするか?(Async エフェクト)
検証のステップ
型を使ったワークフローの各ステップのモデリング#669f464975d04f0000f66140
2 つの依存関係
CheckProduceCodeExists (製品コードの存在チェック)
こちらはエフェクトを用いていない(DMMF p.33)
type CheckProductCodeExists = ProductCode -> bool
CheckAddressExists (アドレスの存在チェック)
こちらは外部サービスを用いているとする(DMMF p.33)
Async エフェクトと Result エフェクトが必要
これらは一緒に使われることが多いため、AsyncResultという型にまとめることが一般的
code:fsharp
type AsyncResult<'success, 'failure> = Async<Result<'success, 'failure>>
code:fsharp
type CheckAddressExists =
UnvalidatedAddress -> AsyncResult<CheckedAddress, AddressValidationError>
I/O 処理をしていて、失敗する可能性があることが 型シグネチャ から明らかになる
自律性 を持たせるために、アドレス検証サービスのローカルバージョンを作るべきか?
境界づけられたコンテキストを利用した解決手段の作成#6684e30a75d04f00009d0c60
可用性 のためならばあり
今回のようにサービスを利用する場合
そのサービスを信頼するか、問題が発生した場合の準備が必要
Result 同様、Async もすべてのコードに伝染する
型を使ったワークフローの各ステップのモデリング#669f4fd175d04f0000e9f9e5
code:fsharp
type ValidateOrder =
CheckProductCodeExists // 依存関係
-> CheckAddressExists // 依存関係
-> UnvalidatedOrder // 入力
-> AsyncResult<ValidatedOrder, ValidationError> // 出力
価格設定のステップ
型を使ったワークフローの各ステップのモデリング#669f4fff75d04f0000e9f9e6
1 つの依存関係
GetProductPrice(製品価格の取得)
エフェクトを用いていない(p.27)
PriceOrder(注文の価格計算)のステップがエラーを返す可能性がある
e.g. 価格が間違っていて、AmountToBill(請求額の合計)が非常に大きく(or マイナス)になる
code:fsharp
type PricingError = PricingError of string
type PriceOrder =
GetProductPrice // 依存関係
-> ValidatedOrder // 入力
-> Result<PricedOrder, PricingError> // 出力
注文確認のステップ
型を使ったワークフローの各ステップのモデリング#669f50bf75d04f0000e9f9fc
2 つの依存関係
CreateOrderAcknowledgmentLetter(注文確認書の作成)
エフェクトを用いていない(p.34)
SendOrderAcknowledgment(注文確認の送信)
メールで送信する(p.35)のでエフェクトを用いている
Async エフェクトを用いる
type SendOrderAcknowledgment = OrderAcknowledgment -> Async<SendResult>
エラーについては気にしない
仕様次第だが、メールアドレスが完全に正しいとしても、以下のようなケースなら失敗するので考慮したほうが良い気がする radish-miyazaki.icon
検証 〜 送信までの間にメールアドレスが失効した
利用している外部のメールサーバが停止している
Async は親関数にも伝搬する
エフェクトの文書化#66a1f6aa75d04f0000cadca1
code:fsharp
type Acknowledgment =
CreateOrderAcknowledgmentLetter // 依存関係
-> SendOrderAcknowledgment // 依存関係
-> PricedOrder // 入力
-> Async<OrderAcknowledgmentSent option> // 出力