[英]F# Fold while building a list using cons (::) as opposed to concat (@)
I have the following function which does what I want. 我有以下功能,它做我想要的。 But is uses the concat (@) operator which is O(n) as opposed to O(1) for the (::) operator 但是使用concat(@)运算符,它是O(n)而不是O(1)运算符
let myFunc s m cs =
let n = s * m
let c = [n - s] // single element list
(n, cs @ c) // concat the new value to the accumulated list
let chgLstAndLast =
[0.99; 0.98; 1.02]
|> List.fold (fun (s, cs) m -> myFunc s m cs) (1., [])
The chgLstAndLast returns the last value and list of the results generated: chgLstAndLast返回最后生成的结果值和列表:
val chgLstAndLast : float * float list = (0.989604, [-0.01; -0.0198; 0.019404])
I would like to improve the above in three ways. 我想以三种方式改进上述内容。
For example, I would like to write a myFunc
like this 例如,我想写一个像这样的myFunc
let myFunc s m cs =
let n = s * m
let c = n - s // single element, but not as list
(n, c) // No concat here
But when I do, I don't see how to use (::) cons in the Fold function. 但是当我这样做时,我没有看到如何在折叠功能中使用(::)缺点。
If I understand your code correctly, what you want to do is a fold
while keeping all intermediary results. 如果我没有理解你的代码,你想要做什么是fold
,同时保持所有的中间结果。 This is almost what List.scan
does; 这几乎就是List.scan
作用; it also returns the initial state. 它也返回初始状态。
let chgLstAndLast data =
let inner s m =
let n = s * m
n, n - s
let processedData = data |> List.scan (fun (s, _) n -> inner s n) (1.0, 1.0)
let lastResult = processedData |> List.reduce (fun _ n -> n)
let seq = processedData |> List.tail |> List.map snd
lastResult, seq
To explain a bit more on this code: first I declare an inner function to make the code cleaner to the exterior world (assuming myFunc
isn't needed by other code), then I use scan
to get all intermediary results from a fold
, which is a built-in way to do your fold + accumulator trick. 为了解释一下这段代码:首先我声明一个内部函数,使代码对外部世界更清晰(假设其他代码不需要myFunc
),然后我使用scan
从fold
获取所有中间结果,是一种内置的方式来做你的折叠+累加器技巧。
The last value is obtained with a reduce
trick since there's no built-in "last of list" function, and the intermediary results are the second parts of the processed data, except for the first element which is the initial state. 最后一个值是通过reduce
技巧获得的,因为没有内置的“last of list”函数,并且中间结果是处理数据的第二部分,除了第一个元素是初始状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.