使用List.collect f#

Don*_*eve 3 .net f# functional-programming

我试图定义一个函数,它接受两个列表并使用List.collect组合它们.

let concat xs xs' = 
    let concatList =  List.collect xs xs'
    printfn "%A" concatList

concat [1;2;3;4] [5;6;7;8]
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:FS0001:此表达式应该具有类型''a->'b list',但这里有类型''c list'

我读到这可能是由于缺少参数,但我不确定这一点.

编辑:

所以我有点像这样工作:

 let concat xs xs' = 
    let concatList =  List.collect (fun x -> xs @ xs') xs
    printfn "%A" concatList

concat [1;2;3;4] [5;6;7;8]
Run Code Online (Sandbox Code Playgroud)

但输出是:[1; 2; 3; 4; 5; 6; 7; 8; 1; 2; 3 4; 5; 6; 7; 8; 1; 2; 3 4; 5; 6; 7; 8; 1; 2; 3 4; 5; 6; 7; 8;]

只希望它是[1; 2; 3 4; 5; 6; 7; 8;]为什么它运行这么多次的任何想法?

编辑2:

所以我得到了这样的工作:

let concat xs xs' = 
    let combList = [[xs];[xs']]
    let concatList =  List.collect id combList
    printfn "%A" concatList

concat [1;2;3;4] [5;6;7;8]
Run Code Online (Sandbox Code Playgroud)

Rin*_*gil 5

正如您在注释中所述,List.collect将函数应用于列表的每个元素.然后,它连接结果并返回一个组合列表.第二种行为是允许你产生类似的行为List.concat.

我们需要做些什么才能实现这一目标?

让我们试着看一下文档示例:

let list1 = [10; 20; 30]
let collectList = List.collect (fun x -> [for i in 1..3 -> x * i]) list1
printfn "%A" collectList
//Output
//[10; 20; 30; 20; 40; 60; 30; 60; 90]
Run Code Online (Sandbox Code Playgroud)

在这个例子中发生的是,对于每个元素list1,我们正在应用该函数(fun x -> [for i in 1..3 -> x * i]).这给了我们与使用时相同的结果List.map.结果是[[10; 20; 30]; [20; 40; 60]; [30; 60; 90]],然后将其连接List.collect到上面的最终结果中.

现在关于你的问题,让我们考虑一个相关的问题.假设我们给出了一个列表,例如

let x = [[10; 20; 30]; [20; 40; 60]; [30; 60; 90]]
Run Code Online (Sandbox Code Playgroud)

我们如何使用List.collect它们来连接它们以获得输出 [10; 20; 30; 20; 40; 60; 30; 60; 90]

因此,List.collect需要一个函数和一个列表.我们可以传入上面定义的列表列表x,但是我们仍然需要一个能够执行映射的函数.但是,我们真的不想对元素进行任何转换,x我们只是想按原样使用它们,这意味着我们应该使用它们id.然后使用

List.collect id x
Run Code Online (Sandbox Code Playgroud)

将返回所需的结果.您的具体问题与上述问题非常相似,不应该太难解决.

  • id只是`fun i - > i`的便利功能 (2认同)