type Cents = int type ChargeId = string nominal OrderId = string type Order = { id: OrderId, totalCents: int, status: "pending" | "paid" } error OrderNotFound = { id: OrderId } error PaymentDeclined = { reason: string } service Orders { find(id: OrderId): Option save(order: Order): void } service Payments { charge(amount: Cents): ChargeId fails PaymentDeclined } const findOrder = (id: OrderId) => Orders.find(id) ?? fail(OrderNotFound({ id })) const chargeOrder = (order: Order) => { retry(() => Payments.charge(order.totalCents), { times: 2 }) order } const markPaid = (order: Order) => ({ ...order, status: "paid" }) const saveOrder = (order: Order) => { Orders.save(order) order } export const pay = (id: OrderId): Order fails OrderNotFound | PaymentDeclined uses Orders | Payments.charge => id |> findOrder |> chargeOrder |> markPaid |> saveOrder