省略可能な値、エラー、およびコレクションのモデリング
省略可能な値のモデリング
code:fsharp
type Option<'a> =
| Some of 'a
| None
Some : 関連付けられた 'a にデータが格納されていることを意味する
None : データがないことを意味する
code:fsharp
type PersonalName = {
MiddleInitial : Option<string>
...
}
以下のようにも書ける
code:fsharp
type PersonalName = {
MiddleInitial : string option
...
}
どちらかというと F# ではこの書き方が好まれている…気がする radish-miyazaki.icon エラーのモデリング
例外もあるが、Result だと「失敗が起こり得る」という事実を型シグネチャで明示的に表現できる
code:fsharp
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TError
Ok : 関数が成功したときの値を格納する
Error : 関数が失敗したときのエラーデータを格納する
ドメインモデルでの使用例
請求書の支払いが失敗する可能性がある場合
code:fsharp
type PayInvoice =
UnpaidInvoice -> Payment -> Result<PaidInvoice, PaymentError>
エラーの型には、起こり得るエラーのケースを持つ選択型をセットする
code:fsharp
type PaymentError =
| CardTypeNotRecognized
| PaymentRejected
| PaymentProviderOffline
値が存在しないことのモデリング
FP ではすべての関数は何かを返さないといけないので、void は使えない 代わりに unit 型を用いる
() という空のペアのみを持つ
乱数生成やデータベース操作など、副作用を扱う際に用いる code:fsharp
type NextRandom = unit -> int
type SaveCustomer = Customer -> unit
リストとコレクションのモデリング
list : 固定サイズのイミュータブルコレクション(連結リスト) array : 固定サイズのミュータブルコレクション
個々の要素がインデックスによって取得・割り当て可能
RedizeArray : 可変サイズの array
要素を追加したり、削除したりできる
seq : 遅延コレクション
各要素が必要に応じて返される
ドメインモデリングでは list を使うことを推奨
code:fsharp
type Order = {
OrderId : OrderId
Lines : OrderLine list
}
作成には、リストリテラルを用いる
code:fsharp
:: 演算子(cons)もサポート
code:fsharp
let aNewList = 0 :: aList
内部の要素にアクセスするには、パターンマッチを用いる
code:fsharp
let printList1 aList =
match aList with
| [] -> printfn "list is empty"
| x -> printfn "list has one element: %A" x | x;y -> printfn "list has two elements: %A and %A" x y | longerList -> printfn "list has more than two elements"
code:fsharp
let printList2 aList =
match aList with
| [] -> printfn "list is empty"
| first::rest ->
printfn "list is non-empty with the first element begin: %A" first