Wild and changing business rules implemented with functional programming
The original requirement


  How can you tame these wild business rules? How can you build a system that will be flexible enough to handle both the complexity and the need for change? And how can you do it without condemning yourself to years and years of mindless support?


seems, to me, to insinuate some sort of generic rules engine. This is, I believe, a red herring. The problem with rules engines, in my experience, is that the selling point is always that 'business users' can maintain them without involving developers.

This is a pipe dream, because if business rules can be arbitrarily complex, you're going to need a rules engine that can handle all of this complexity. In other words, you're going to need a programming language, and then it becomes too technical for business users.

This is called the inner platform effect and is, in my opinion, best avoided.

So you might as well use a programming language to implement the rules, and I see no reason you can't use a functional language like F#.

Here's a sketch of some of the rules. Like in the real world, some of the rules are vaguely defined, so I wasn't sure how to interpret them...

type Membership = Basic | Gold

type Good =
| PhysicalProduct of string
| Book of string
| Video of string
| Membership of Membership
| Upgrade

type Command =
| Slip of string * (Good list)
| Activate of Membership
| Upgrade
| PayAgent


These are simply some types, but given these types, you can implement various business rules, e.g.

// Good -&gt; Command list
let slipForShipping = function
| PhysicalProduct name
| Book name
| Video name -&gt; [Slip ("Shipping", [PhysicalProduct name])] 
| _ -&gt; []

// Good -&gt; Command list
let slipForRoyalty = function
| Book name -&gt; [Slip ("Royalty", [Book name])]
| _ -&gt; []

// Good -&gt; Command list
let activate = function | Membership x -&gt; [Activate x] | _ -&gt; []

// Good -&gt; Command list
let upgrade = function | Good.Upgrade -&gt; [Upgrade] | _ -&gt; []


You'll notice that all these rules have the same type, which means that you can collect all of them:

// ('a -&gt; 'b list) list -&gt; 'a -&gt; 'b list
let handle handlers good = handlers |&gt; List.collect (fun h -&gt; h good)

// Good -&gt; Command list    
let handleAll = handle [slipForShipping; slipForRoyalty; activate; upgrade]


Example:

&gt; handleAll (Book "The Annotated Turing");;
val it : Command list =
  [Slip ("Shipping",[PhysicalProduct "The Annotated Turing"]);
   Slip ("Royalty",[Book "The Annotated Turing"])]


As far as I can tell, this would be fairly maintainable, because if you need to add a new rule, you'll have to add a new function, and add that function to handleAll.