摆脱",;“末日金字塔”;在F#

摆脱",;“末日金字塔”;在F#,f#,F#,我将几个口头表达打包成一个函数: open FsVerbalExpressions open FsVerbalExpressions.VerbalExpression open System.Text.RegularExpressions open System let createOrVerbExFromList (verbExList: VerbEx list) = let orVerbEx = verbExList |> List.red

我将几个口头表达打包成一个函数:

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"

我想重写
newInst
函数,使它不再是“末日金字塔。我的问题是我怎样才能摆脱厄运金字塔?我能把它处理掉吗?我怀疑这将是某种
异步
工作流或其他计算表达式,但这些对我来说都是全新的。

如果你只匹配布尔值,那么
如果。。。elif
足够:

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"
更灵活的可能性是创建一个活动模式:

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"

当存在完全相同形式的代码的顺序重复时,我更喜欢使用数据驱动的方法:

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"

这种方法的一个优点是原始数据(
verbExStrings
)可以在其他地方派上用场,并且与代码实现无关。

这是对活动模式的一个很好的介绍。您能告诉我活动模式中附加的
|
的意义吗?
|
表示部分活动模式,这意味着它可能不匹配所有值(这就是它返回选项的原因)。关于总AP和部分AP之间的差异。在您的情况下,您可能实际上想要编写一个完整的AP,但它的实现本身将受到相同的厄运金字塔的影响:)