【发布时间】:2022-01-05 18:51:11
【问题描述】:
一个简单的例子,灵感来自this question:
module SimpleExample =
let fooFold projection folder state source =
source |> List.map projection |> List.fold folder state
// val fooFold :
// projection:('a -> 'b) ->
// folder:('c -> 'b -> 'c) -> state:'c -> source:'a list -> 'c
let fooReduce projection reducer source =
source |> List.map projection |> List.reduce reducer
// val fooReduce :
// projection:('a -> 'b) -> reducer:('b -> 'b -> 'b) -> source:'a list -> 'b
let game = [0, 5; 10, 15]
let minX, maxX = fooReduce fst min game, fooReduce fst max game
let minY, maxY = fooReduce snd min game, fooReduce snd max game
在本例中,函数 fooFold 和 fooReduce 的自然名称是什么?唉,mapFold 和 mapReduce 已经被占用了。
mapFold 是 F# 库的一部分,对输入执行 fold 操作以返回 'result list * 'state 的元组,类似于 scan,但没有初始状态并且需要将元组提供为自己的状态的一部分。它的signature 是:
val mapFold : ('State -> 'T -> 'Result * 'State) -> 'State -> 'T 列表 -> '结果列表 * '状态
由于投影可以很容易地集成到文件夹中,fooFold 函数仅用于说明目的。
还有MapReduce:
MapReduce 是一种算法,用于处理特定的大型数据集 使用大量节点的各种可分布问题
现在来看一个更复杂的示例,其中fold/reduce 不直接应用于输入,而是应用于选择键后的分组。
该示例是从 a Python library 借用的,它被称为 - 可能具有误导性 - reduceby。
module ComplexExample =
let fooFold keySelection folder state source =
source |> Seq.groupBy keySelection
|> Seq.map (fun (k, xs) ->
k, Seq.fold folder state xs)
// val fooFold :
// keySelection:('a -> 'b) ->
// folder:('c -> 'a -> 'c) -> state:'c -> source:seq<'a> -> seq<'b * 'c>
// when 'b : equality
let fooReduce keySelection projection reducer source =
source |> Seq.groupBy keySelection
|> Seq.map (fun (k, xs) ->
k, xs |> Seq.map projection |> Seq.reduce reducer)
// val fooReduce :
// keySelection:('a -> 'b) ->
// projection:('a -> 'c) ->
// reducer:('c -> 'c -> 'c) -> source:seq<'a> -> seq<'b * 'c>
// when 'b : equality
type Project = { name : string; state : string; cost : decimal }
let projects =
[ { name = "build roads"; state = "CA"; cost = 1000000M }
{ name = "fight crime"; state = "IL"; cost = 100000M }
{ name = "help farmers"; state = "IL"; cost = 2000000M }
{ name = "help farmers"; state = "CA"; cost = 200000M } ]
fooFold (fun x -> x.state) (fun acc x -> acc + x.cost) 0M projects
// val it : seq<string * decimal> = seq [("CA", 1200000M); ("IL", 2100000M)]
fooReduce (fun x -> x.state) (fun x -> x.cost) (+) projects
// val it : seq<string * decimal> = seq [("CA", 1200000M); ("IL", 2100000M)]
这里的函数fooFold 和fooReduce 的自然名称是什么?
【问题讨论】:
标签: f# mapreduce terminology fold