Getting rid of the “pyramid of doom” in F#

后端 未结 2 2020
孤独总比滥情好
孤独总比滥情好 2020-12-20 15:25

I have several verbal expressions that I\'ve packaged into one function:

open FsVerbalExpressions
open FsVerbalExpressions.VerbalExpression
open System.Text.         


        
相关标签:
2条回答
  • 2020-12-20 16:13

    If you are only matching against booleans, then if ... elif is sufficient:

    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 possibility would be to create an active pattern:

    let (|IsMatch|_|) f x =
        if isMatch x f 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"
    
    0 讨论(0)
  • 2020-12-20 16:17

    When there is sequential repetition of exactly the same form of code, I prefer to use a data-driven approach instead:

    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"
    

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

    0 讨论(0)
提交回复
热议问题