我是F#的新手,我似乎在获取列表总和方面遇到了问题。
let listOne = [1 .. 10]
let listTwo = listOne.Select(fun i -> i * 2).ToList()
let result = List.sum listTwo
result.Dump()
但是,以下代码会产生此错误:
This expression was expected to have type 'a list but here has type List<int>
非常感谢任何有关他们与众不同的见解
答案 0 :(得分:4)
F#整数列表不是List<T>
(即List<int>
)。
这就是它抛出此类错误的原因:List<T>
不是FSharpList<T>
当您致电IEnumerable<T>.Select
时,您正在将FSharpList<int>
转换为IEnumerable<int>
,然后IEnumerable<T>.ToList()
会返回List<int>
。
此外,您应该使用IEnumerable<T>.Sum(...)
:
let result = listTwo.Sum();
此外,您无需将IEnumerable<int>
转换为List<int>
:.Sum(...)
是IEnumerable<T>
界面的成员。
答案 1 :(得分:1)
let listOne = [1 .. 10]
let listTwo = listOne.Select(fun i -> i * 2).ToList()
listOne : int list (alias for Microsoft.FSharp.Collections.List<int>) listTwo : System.Collections.Generic.List<int>
如您所见,listOne和listTwo的类型完全不同。
答案 2 :(得分:0)
就像已发布的那样,问题是F#有自己的List-Type,它支持所有的流水线操作等。
要将使用Linq获得的.NET-List或IEnumerable转换为F#-List,您可以使用 List.ofSeq
或 List.ofArray
< / strong>如下:
let listOne = [1 .. 10]
let listTwo = listOne.Select(fun i -> i * 2).ToList()
let result = List.sum (List.ofSeq listTwo)
答案 3 :(得分:0)
Matias Fidemraizer很好地解释了这个问题,但是可以在F#中更加惯用地解决您的问题,而根本不使用Linq。使用Select
模块中的F#ToList
函数代替map
和List
:
let listOne = [1 .. 10]
let listTwo = List.map (fun i -> i * 2) listOne
let result = List.sum listTwo
您也可以使用管道运算符一次完成所有操作:
let result = [1 .. 10] |> List.map (fun i -> i * 2) |> List.sum
您还可以使用部分功能应用程序代替fun
关键字:
let result = [1 .. 10] |> List.map ((*) 2) |> List.sum
您还可以使用sumBy函数并避免在内存中创建第二个列表:
let result = [1 .. 10] |> List.sumBy ((*) 2)