在F#中,我找不到基于内部集合中项目属性查询集合的直观方法。例如,考虑一下地址簿的场景。它包含多个人员记录,每个人可以有多个电子邮件地址或电话号码。类型是:
type Email = {Email : string}
type PhoneNumber = {Number : string}
type Person = {Name : string; EmailAdresses : seq<Email>; PhoneNumbers : seq<PhoneNumber>}
我想写一个试图根据电话号码找人的功能。由于电话号码是唯一的,我希望该功能可以返回一个人或没有人,例如功能签名变为
string->seq<Person>->Person option
我想出了
let ``find person by phone number`` number ppl=
ppl |> Seq.tryFind(fun r -> Seq.exists (fun p -> p.Number = number) r.PhoneNumbers)
Q1:在我看来,这个查询不是很易读,可以用任何清洁工写吗?
Q2:我也希望能够查询其他内部集合,例如电子邮件地址。我不想定义另一个函数find person by email address
,而是想探索更通用的方法。以下作品:
let findPerson (propSelector : Person -> seq<'a>) (pred : seq<'a> -> bool) ppl =
ppl |> Seq.tryFind (propSelector >> pred)
(为了清晰起见,包括类型。)要调用此函数,我必须
ppl |> findPerson (fun x -> x.EmailAdresses) (fun p -> p |> Seq.exists (fun n -> n.Email = "john.doe@nowhere.com"))
再一次,lambdas变得丑陋,尤其是第二个。有关如何改进此代码的任何建议吗?