我有以下函数,用于检查数据源中customer
的存在并返回ID。这是使用Option
类型的正确/惯用方式吗?
let findCustomerId fname lname email =
let (==) (a:string) (b:string) = a.ToLower() = b.ToLower()
let validFName name (cus:customer) = name == cus.firstname
let validLName name (cus:customer) = name == cus.lastname
let validEmail email (cus:customer) = email == cus.email
let allCustomers = Data.Customers()
let tryFind pred = allCustomers |> Seq.tryFind pred
tryFind (fun cus -> validFName fname cus && validEmail email cus && validLName lname cus)
|> function
| Some cus -> cus.id
| None -> tryFind (fun cus -> validFName fname cus && validEmail email cus)
|> function
| Some cus -> cus.id
| None -> tryFind (fun cus -> validEmail email cus)
|> function
| Some cus -> cus.id
| None -> createGuest() |> fun cus -> cus.id
最佳答案
当您缩进缩进永远都不是一件好事,因此值得一看的是您能做些什么。
通过引入一些辅助功能,这是解决问题的一种方法:
let tryFindNext pred = function
| Some x -> Some x
| None -> tryFind pred
您可以在
findCustomerId
函数中使用它来展平后备选项:let findCustomerId' fname lname email =
let (==) (a:string) (b:string) = a.ToLower() = b.ToLower()
let validFName name (cus:customer) = name == cus.firstname
let validLName name (cus:customer) = name == cus.lastname
let validEmail email (cus:customer) = email == cus.email
let allCustomers = Data.Customers()
let tryFind pred = allCustomers |> Seq.tryFind pred
let tryFindNext pred = function
| Some x -> Some x
| None -> tryFind pred
tryFind (fun cus -> validFName fname cus && validEmail email cus && validLName lname cus)
|> tryFindNext (fun cus -> validFName fname cus && validEmail email cus)
|> tryFindNext (fun cus -> validEmail email cus)
|> function | Some cus -> cus.id | None -> createGuest().id
这与the approach outlined here非常相似。