具有模式匹配功能的F#分支逻辑

A19*_*919 2 f#

让我在C#上有这样的代码。如何用F#在函数样式中重写此早午餐逻辑?我应该使用什么模式匹配?主动模式匹配?区分工会?

public class DataBase
{
    public List<string> GetEmployees(string id, string email)
    {
        if (!string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(email))
        {
            return GetByIdAndEmail(id, email);
        }
        else if (!string.IsNullOrEmpty(email))
        {
            return GetByEmail(email);
        }
        else if (!string.IsNullOrEmpty(id))
        {
            return GetById(id);
        }
        else
        {
            return new List<string>();
        }
    }

    private List<string> GetByIdAndEmail(string id, string email)
    {
        // request something in db
        return new List<string>() { "First" };
    }

    private List<string> GetByEmail(string email)
    {
        //request something in db
        return new List<string>() { "Second" };
    }

    private List<string> GetById(string id)
    {
        // request something in db
        return new List<string>() { "Third" };
    }
}

class Program
{
    static void Main(string[] args)
    {
        DataBase DB = new DataBase();
        string id = null;
        string email = null;
        DB.GetEmployees(id, email);
    }
}
Run Code Online (Sandbox Code Playgroud)

F#

let GetEmployees (id:string)(email:string) = 
    match (id,email) with
    ...
Run Code Online (Sandbox Code Playgroud)

Ngh*_*Bui 6

我认为这已经足够了:

let getByIdAndEmail id email = ["First"]
let getByEmail email = ["Second"]
let getById id = ["Third"]

let getEmployees id email = 
    match String.IsNullOrEmpty id, String.IsNullOrEmpty email with
    | false, false -> getByIdAndEmail id email 
    | true, false  -> getByEmail email
    | false, true  -> getById id
    | _ -> []
Run Code Online (Sandbox Code Playgroud)

如果您想利用F#类型系统的功能及其简洁的语法,我建议您进一步编写一个新的字符串类型,以确保其内容不为null或为空。这样,使用该类型的值时,每个人都会感到安全。

type ReallyString = private ReallyString of string with
    static member Create s = match String.IsNullOrEmpty s with
                             | true -> None
                             | false -> Some (ReallyString s)
    member this.Value = let (ReallyString s) = this in s

let getByIdAndEmail (id : ReallyString) (email : ReallyString) =
    // Yay, I feel safe because the id and email really have content
    // I can use id.Value and email.Value without any worry
    ["First"]
let getByEmail (email : ReallyString) =
    // Yay, I feel safe because the email really has content
    // I can use email.Value without any worry
    ["Second"]
let getById (id : ReallyString) =
    // Yay, I feel safe because the id really has content
    // I can use id.Value without any worry
    ["Third"]

let getEmployees id email =
    // I feel unsafe here, so I have to check
    // Actually I'm being forced to check because if I don't check
    // I won't have valid values to pass to the getByXXX functions above
    match ReallyString.Create id, ReallyString.Create email with
    | Some reallyId, Some reallyEmail -> getByIdAndEmail reallyId reallyEmail
    | Some reallyId, None -> getById reallyId
    | None, Some reallyEmail -> getByEmail reallyEmail
    | _ -> []
Run Code Online (Sandbox Code Playgroud)