为什么foldBack的签名与F#中的fold有如此大的不同?
至少有两件事我不明白:为什么foldBack的签名与F#中的fold有如此大的不同?,f#,F#,至少有两件事我不明白: 从左侧折叠到右侧折叠的重构不仅需要在签名上进行大量更改,而且需要在每个地方进行大量更改,这取决于文件夹功能 如果不翻转参数,就无法根据列表链接它 List.foldBack:('T->'State->'State)->'T List->'State->'State List.fold:('State->'T->'State)->'State->'T List->'State 与折叠相比,为什么有人在折叠的签名中把所有参数都倒过来?这只是一个有用的助记符,可以帮助程序员
- 从左侧折叠到右侧折叠的重构不仅需要在签名上进行大量更改,而且需要在每个地方进行大量更改,这取决于文件夹功能
- 如果不翻转参数,就无法根据列表链接它
List.foldBack:('T->'State->'State)->'T List->'State->'State
List.fold:('State->'T->'State)->'State->'T List->'State
与
折叠
相比,为什么有人在折叠
的签名中把所有参数都倒过来?这只是一个有用的助记符,可以帮助程序员记住列表是如何迭代的。想象一下,你的清单是从左开始,右结束的<代码>折叠从左侧的初始状态开始,然后累积到右侧的状态<代码>折叠执行相反的操作,它从右侧的初始状态开始,然后返回到左侧的列表
这无疑显示了F#的OCaml遗产,因为其他一些函数式语言(Haskell、Scala、ML)将列表作为最后一个参数,以允许更常见的部分应用程序场景
如果我真的需要一个类似于折叠的版本,我会定义自己的助手函数:
module List =
let foldBack' f acc lst =
let flip f a b = f b a
List.foldBack (flip f) lst acc
这是F#在OCaml的起源的遗迹。您可以看到,List.fold
和List.foldBack
的F#函数签名在中是相同的(分别称为List.fold#left
和List.fold#right
)。而且,如果不打破大量的代码,它是永远不会改变的。我认为,一旦你对每个人的行为有了正确的思维模式,签名就会自然而然地读出。同样在懒惰的语言中,也有很好的理由让这些人分开。但我认为这是一个有效的问题。保留列表作为最后一个参数,以考虑更常见的部分应用场景。当涉及到F#中的折叠时,情况并非如此。是的,他是这么说的。