F# 创建从其他列表填充的新列表

F# create new list populated from other list

在我的后端代码中,我从数据库中获取数据并且我的查询 return 是一个产品对象列表。但是,由于我不需要 return 所有产品对象的数据到前端,我想选择 returned 属性(即不是产品对象的所有属性).

我正在尝试使用 List.map 仅选择部分属性。

let products = session.Query<Product<IProductVariant>>("where id < 1000")
let returnValue = List.collect(fun product -> (product.ID, product.Name)) products

但是上面的方法不起作用,因为“product”是一个对象,而不是 Product class 的一个实例。我试过像这样再次格式化它,但无济于事。

let returnValue = List.map(fun obj -> (
   match (obj) with
   | ProductClass product -> (product.ID, product.Name)
   | None -> ignore
)) products

自从在工作中继承了一个F#项目的维护后,我才开始学习F#。所以,我尝试的解决方案可能是完全错误的方向。如果我的解决方案尝试完全错误,请告知如何继续。

虽然我无法重现问题,但没有您未指定的部分的简化版本可能是:

type Product = { Id: int; Name: string; Price: decimal }
let products = [ { Id = 42; Name = "Waterfall"; Price = 3.14m } ]
let retVal = List.map (fun p -> (p.Id, p.Name)) products

在这里,F# 推断 retVallist<int * string> 类型。

让我们假设,无论出于何种原因,类型都有些错误。我们可以挑起这个:

open System
type Product = { Id: int; Name: string; Price: decimal }
let products = [ { Id = 42; Name = "Waterfall"; Price = 3.14m } ]
type WrongProduct = { Id: Guid; Name: string option }
let retVal = List.map (fun p -> (p.Id, p.Name)) products

WrongProduct 的简单加法导致

error FS0001: Type mismatch.

我们(至少)可以做两件事:

在映射函数中指定参数类型:

let retVal = List.map (fun (p: Product) -> (p.Id, p.Name)) products

或将乘积通过管道传递到映射函数中,这样编译器 'knows' 查看函数时元素的类型:

let retVal = products |> List.map (fun p: Product -> (p.Id, p.Name))

后者是 F# 中的惯用方式