How to avoid long pattern matching functions?

When using union types with multiple constructors, I almost always render a lot of logic in a single function, i.e. handling all cases in one function. Sometimes I would like to extract logic for a particular case to separate a function, but you cannot have a function that takes only one "constructor" as a parameter.

Example: Suppose we have a typical type of expression:

type Formula =    
| Operator of OperatorKind * Formula * Formula
| Number of double   
| Function of string * Formula list
[...]

Then we would like to evaluate the expression:

let rec calculate efValues formula = 
match formula with
    | Number n -> [...] 
    | Operator (kind, lFormula, rFormula) -> [...]
    | [...]

Such a function will be very long and increasing with each new Formula constructor. How can I avoid this and clear such code? Long-lasting pattern matching designs are inevitable?

+4
source share
2 answers

Operator Formula, :

type Formula =    
 | Operator of (string * Formula * Formula)
 | Number of double   

, Operator(name, left, right), Operator args, - :

let evalOp (name, l, r) = 0.0
let eval f = 
  match f with
 | Number n -> 0.0
 | Operator args -> evalOp args

, ( ):

type OperatorInfo = string * Formula * Formula
and Formula =    
 | Operator of OperatorInfo
 | Number of double   

, , :

type OperatorInfo = 
 { Name : string
   Left : Formula 
   Right : Formula }
and Formula =    
 | Operator of OperatorInfo
 | Number of double   

, :

| Operator args -> (...)
| Operator { Name = n; Left = l; Right = r } -> (...)
+3

, . - . , , .

, , :

 let doSomethingForOneCase (form: Formula) =
     match form with
     | Formula (op, l, r) -> 
         let result = (...)
         Some result
     | _ -> None

None , .

, , , , , case , , .

+2

Source: https://habr.com/ru/post/1569758/


All Articles