让我在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)
我认为这已经足够了:
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)