gpt4 book ai didi

f# - 使用一个枚举应用多个聚合函数

转载 作者:行者123 更新时间:2023-12-01 07:57:59 24 4
gpt4 key购买 nike

假设我有一系列作用于一个序列的函数,我想按以下方式一起使用它们:

let meanAndStandardDeviation data = 
let m = mean data
let sd = standardDeviation data
(m, sd)

上面的代码将枚举序列两次。我对一个能给出相同结果但只枚举序列一次的函数感兴趣。这个函数将是这样的:

magicFunction (mean, standardDeviation) data

其中输入是一个函数元组和一个序列,输出与上面的函数相同。

如果函数 meanstadardDeviation 是黑盒子并且我无法更改它们的实现,这是否可能?

如果我自己写meanstandardDeviation,有没有办法让它们一起工作?也许以某种方式让他们继续为下一个函数产生输入并在完成后移交结果?

最佳答案

当函数是黑盒时,使用一次迭代来做到这一点的唯一方法是使用 Seq.cache函数(对序列进行一次评估并将结果存储在内存中)或将序列转换为其他内存中表示形式。

当函数采用 seq<T> 时作为参数,您甚至不能保证它只会对其进行一次评估 - 标准差的通常实现将首先计算平均值,然后再次迭代序列以计算误差的平方。

我不确定您是否可以仅通过一次计算就可以计算出标准偏差。但是,如果使用 fold 表示函数,则可以这样做.例如,使用两次通过计算最大值和平均值如下所示:

let maxv = Seq.fold max Int32.MinValue input
let minv = Seq.fold min Int32.MaxValue input

您可以像这样使用单次传递来做到这一点:

Seq.fold (fun (s1, s2) v -> 
(max s1 v, min s2 v)) (Int32.MinValue, Int32.MaxValue) input

lambda 函数有点难看,但你可以定义一个组合子来组合两个函数:

let par f g (i, j) v = (f i v, g j v)
Seq.fold (par max min) (Int32.MinValue, Int32.MaxValue) input

此方法适用于可以使用 fold 定义的函数,这意味着它们包含一些初始值(第一个示例中的 Int32.MinValue),然后是一些用于在获取下一个值时更新初始(先前)状态的函数(然后可能是一些后处理结果)。一般来说,应该可以用这种风格重写单遍函数,但我不确定这是否可以用于标准偏差。绝对可以做到:

let (count, sum) = Seq.fold (fun (count, sum) v -> 
(count + 1.0, sum + v)) (0.0, 0.0) input
let mean = sum / count

关于f# - 使用一个枚举应用多个聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10166626/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com