01
Model the messy parts
Records, unions, options, and exhaustive matching make business rules readable instead of fragile.
type Decision =
| Approve of int
| Review of string
| Decline
let decide score =
match score with
| n when n > 80 -> Approve 5000
| n when n > 55 -> Review "manual"
| _ -> Decline
02
Hand it capabilities
Scripts only reach the functions your host exposes. The integration boundary is explicit and typed.
let notifyLateInvoice invoice =
match invoice.Status with
| "late" ->
Host.notify invoice.Owner
$"Invoice {invoice.Id} is late"
| _ ->
()
03
Ship rules, not rebuilds
Load once, discover exports, and invoke them by name from .NET or JavaScript hosts.
type Event = { Kind: string }
[<export>] let route (event: Event) =
match event.Kind with
| "signup" -> "onboarding"
| "payment.failed" -> "billing"
| "churn.risk" -> "success"
| _ -> "archive"