我有以下函数,用于检查数据源中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非常相似。

10-07 23:34