F#是否具有折叠列表功能?
F#是否具有折叠列表功能?,f#,fold,F#,Fold,Mathematica和其他语言可能都有一个foldList函数。它非常类似于fold,但它不是只返回最终的计算值,而是返回每个中间值 在F#中编写折叠列表函数并不难: 让折叠列表f(x:S)(m:list)(y:T)=(f(Seq.head xs)y)::xs List.fold fs[x]m |>List.rev 设m=[1;2;-3;5] 折叠列表(+)0米 //val-it:int-list=[0;1;3;0;5] List.fold(+)0米 //val it:int=5 F#中有这
Mathematica
和其他语言可能都有一个foldList
函数。它非常类似于fold,但它不是只返回最终的计算值,而是返回每个中间值
在F#中编写折叠列表
函数并不难:
让折叠列表f(x:S)(m:list)(y:T)=(f(Seq.head xs)y)::xs
List.fold fs[x]m
|>List.rev
设m=[1;2;-3;5]
折叠列表(+)0米
//val-it:int-list=[0;1;3;0;5]
List.fold(+)0米
//val it:int=5
F#中有这样的函数吗?
如果没有,是否有比上述更有效的实施方案?
有没有办法避免调用List.rev?是的,这是一个内置函数,叫做
为了回答您关于反转列表的问题,FSharp.Core中的实现避免了使用变异来反转列表。此可变API未公开。如果您感兴趣,您可以找到源代码。您能否在
List.rev
中详细介绍一下突变是如何发生的?我看到评论说“基于变异的实现”,但我没有发现它。我可以在其他库函数中看到变异代码的使用,但对于您误解的List.rev
@AntonSchwaighofer,我看不到。问题是要避免颠倒清单。变异不是发生在List.rev
中,而是发生在List.scan
中,以避免需要反转列表。好的,现在有意义了。@TheInnerLight-在scan
中的变异是否对异步、并发或并行处理有影响?@Soldalma否,不是外部,scan
不会改变您提供的列表,只会改变它作为返回值构建的本地列表。如果FSharp.Core中的scan
实现使用了上述一些技术,那么肯定会导致不必要的行为。谢天谢地,它并没有做到这一点。
let foldList f (x: 'S) (m: list<'T>) =
let fs (xs: list<'S>) (y: 'T) = (f (Seq.head xs) y)::xs
List.fold fs [x] m
|> List.rev
let m = [1; 2; -3; 5]
foldList (+) 0 m
// val it : int list = [0; 1; 3; 0; 5]
List.fold (+) 0 m
// val it : int = 5
let m = [1; 2; -3; 5]
List.scan (+) 0 m;;
//val it : int list = [0; 1; 3; 0; 5]