Getting rid of the “death pyramid" in F #

I have several verbal expressions that I have packed into one function:

open FsVerbalExpressions open FsVerbalExpressions.VerbalExpression open System.Text.RegularExpressions open System let createOrVerbExFromList (verbExList: VerbEx list) = let orVerbEx = verbExList |> List.reduce (fun acc thing -> verbExOrVerbEx RegexOptions.IgnoreCase acc thing) //simpleVerbEx orVerbEx let k12VerbEx = let kTo12 = ["SCHOOL"; "DIST"; "SD"; "HS"; "BD OF ED"] kTo12 |> List.map (fun word -> VerbEx(word)) |> createOrVerbExFromList let twoYearCollegeVerbEx = VerbEx("2 Year College") let universityVerbEx = VerbEx("UNIV") let privateSchoolVerbEx = VerbEx("ACAD") //Here there be dragons: let newInst (x: string) = match (isMatch x k12VerbEx) with | true -> "K - 12" | _ -> match (isMatch x twoYearCollegeVerbEx) with | true -> "2 Year College" | _ -> match (isMatch x universityVerbEx) with | true -> "University" | _ -> match (isMatch x privateSchoolVerbEx) with | true -> "Private / Charter School" | _ -> "Other" 

I would like to rewrite the newInst function newInst that it is no longer the "death pyramid." My question is: how can I get rid of the pyramid of death? Can I get rid of her? I have a suspicion that this will be some kind of async workflow or other computational expression, but for me all this is very new.

+7
f #
source share
2 answers

If you are only matched with booleans, then if ... elif enough:

 let newInst (x: string) = if isMatch x k12VerbEx then "K - 12" elif isMatch x twoYearCollegeVerbEx then "2 Year College" elif isMatch x universityVerbEx then "University" elif isMatch x privateSchoolVerbEx then "Private / Charter School" else "Other" 

A more flexible option would be to create an active template:

 let (|IsMatch|_|) fx = if isMatch xf then Some () else None let newInst (x: string) = match x with | IsMatch k12VerbEx -> "K - 12" | IsMatch twoYearCollegeVerbEx -> "2 Year College" | IsMatch universityVerbEx -> "University" | IsMatch privateSchoolVerbEx -> "Private / Charter School" | _ -> "Other" 
+16
source share

When a sequential repetition of exactly the same form of code occurs, I prefer to use a data-based approach:

 let verbExStrings = [ (k12VerbEx, "K - 12") (twoYearCollegeVerbEx, "2 Year College") (universityVerbEx, "University") (privateSchoolVerbEx, "Private / Charter School") ] let newInst x = verbExStrings |> List.tryPick (fun (verbEx, string) -> if isMatch x verbEx then Some string else None) |> function Some x -> x | _ -> "Other" 

The advantage of this approach is that raw data ( verbExStrings ) can come in handy in other places and are not tied to your code implementation.

+3
source share

All Articles