I decided to move on to the next stage of the Business Rules kata.
Again, I decided to go function first instead of type first.
I followed the same design pattern that Mark Seeman had introduced to me.
Thus, I wrote the following solution:
module PaymentsImpl (*Types*) type ClientCredit = HaveCredit | NoCredit type PaymentStatus = | CreditAndInStock | CreditAndOutStock | CheckAndInStock | CheckAndOutStock | POAndInStock of ClientCredit | POAndOutStock of ClientCredit | POPayment | NoPayment type Command = | AcceptPayment | HoldPayment | WaitForPayment | Ship | SendInvoice (*Functions*) let isAuthorized = function | HaveCredit -> true | _ -> false let handlePayment = function | POAndInStock _ -> None | NoPayment -> Some WaitForPayment | POAndOutStock _ | CheckAndOutStock | CreditAndOutStock -> Some HoldPayment | POPayment _ | CreditAndInStock | CheckAndInStock -> Some AcceptPayment let handleShipping = function | CreditAndInStock | CheckAndInStock -> Some Ship | POAndInStock status -> if isAuthorized status then Some Ship else None | _ -> None let handleInvoice = function | POAndInStock credit when isAuthorized credit -> Some SendInvoice | _ -> None let handleAll handlers status = handlers |> List.choose(fun handle -> handle status) (*Client*) let result = handleAll [ handlePayment handleShipping handleInvoice ] (POAndInStock NoCredit)