[英]F# Fold while building a list using cons (::) as opposed to concat (@)
我有以下功能,它做我想要的。 但是使用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., [])
chgLstAndLast返回最后生成的结果值和列表:
val chgLstAndLast : float * float list = (0.989604, [-0.01; -0.0198; 0.019404])
我想以三种方式改进上述内容。
例如,我想写一个像这样的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
但是当我这样做时,我没有看到如何在折叠功能中使用(::)缺点。
如果我没有理解你的代码,你想要做什么是fold
,同时保持所有的中间结果。 这几乎就是List.scan
作用; 它也返回初始状态。
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
为了解释一下这段代码:首先我声明一个内部函数,使代码对外部世界更清晰(假设其他代码不需要myFunc
),然后我使用scan
从fold
获取所有中间结果,是一种内置的方式来做你的折叠+累加器技巧。
最后一个值是通过reduce
技巧获得的,因为没有内置的“last of list”函数,并且中间结果是处理数据的第二部分,除了第一个元素是初始状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.