F# 中的嵌套 if 语句与模式匹配

Nested if statements vs pattern matching in F#

我在 C# 中有一个函数可以检查学生是否参加了所有考试:

public Tuple<bool, string> HasTakenAllExams (string parameters)
{
    // get the collection from db based on built query

    if (parameters.Contains("FullTime"))
    {
        if (collection.English == null) { return new Tuple<bool, string>(false, "Value of English is null"); }
        if (collection.Maths == null) { return new Tuple<bool, string>(false, "Value of Maths is null"); }
        if (collection.PE == null) { return new Tuple<bool, string>(false, "Value of PE is null"); }
    }
    if (collection.Biology == null) { return new Tuple<bool, string>(false, "Value of Biology is null"); }

    return new Tuple<bool, string>(true, null);
}

我用 F# 重写了它看起来像这样:

let HasTakenAllExams parameters : (bool * string) =
    // get the collection from db based on built query
    let mutable someStringMessage = ""
    let mutable someBooleanValue = true
    if (parameters:string).Contains("FullTime") then
        if collection.English == null then someStringMessage <- "Value of English is null"; someBooleanValue <- false
        if collection.Maths == null then someStringMessage <- "Value of Maths is null"; someBooleanValue <- false
        if collection.PE == null then someStringMessage <- "Value of PE is null"; someBooleanValue <- false
    if collection.Biology == null then someStringMessage <- "Value of Biology is null"; someBooleanValue <- false
    (someBooleanValue, someStringMessage)

我猜测嵌套的 if 语句不是 "best practice" 函数式编程和模式匹配的方式?

if (parameters:string).Contains("FullTime") then
    match collection.English with
    | null -> someStringMessage <- "Value of English is null"; someBooleanValue <- false
    match collection.Maths with
    | null -> someStringMessage <- "Value of Maths is null"; someBooleanValue <- false
    match collection.PE with
    | null -> someStringMessage <- "Value of PE is null"; someBooleanValue <- false
else
    match collection.Biology with
    | null -> someStringMessage <- "Value of Biology is null"; someBooleanValue <- false

有没有better/more有效的方法来编写上面的代码?

我会像这样编写与您的 C# 函数等效的模式匹配(我缩写了 parameterscollection):

let hasTookExams (prams: string) = 
    match prams.Contains("FullTime"), coll.English, coll.Maths, coll.PE, coll.Biology with
    | true, null, _, _, _ -> (false, "Value of English is null")
    | true, _, null, _, _ -> (false, "Value of Maths is null")
    | true, _, _, null, _ -> (false, "Value of PE is null")
    | _,    _, _, _, null -> (false, "Value of Biology is null") 
    | _                   -> (true, null)