【问题标题】:How to properly implement reduce function in F#如何在 F# 中正确实现 reduce 函数
【发布时间】:2021-01-26 01:35:31
【问题描述】:

我对 F# 和学习列表很陌生。我很难尝试实现自己的 reduce 函数。我一直在尝试实现这一点。这是我到目前为止所拥有的,但我收到一个错误,当调用 reduce 时说我传入的列表是 type 是 int 类型,但应该是 type 'a list.我对此感到非常沮丧,因此欢迎任何帮助。

我的代码如下所示:

let reduce Fn (list: 'a list) = 
      let rec innerFun list acc =
          match list with
          | (x::xs) :: xss ->
              let newAcc = Fn x xs // the fn applied to the head and the next element
              innerFun xss newAcc // recurse through the list with new accumulator
          | [] -> acc // if the list is empty return the accumulator
      innerFun list 0 
               
   //Calling reduce            
   let red2 = reduce (fun x y -> x*y) [23; 4]

【问题讨论】:

  • 您在示例中缺少部分函数定义?
  • 为您提供了有关您遇到的问题的答案,但在您的实施中存在一些问题。将其行为与内置的 List.reduce 进行比较,特别是对于空列表和单元素列表。

标签: functional-programming f#


【解决方案1】:

您遇到的直接问题实际上非常简单且纯粹是句法:

match list with
| (x::xs) :: xss ->

括号使模式匹配列表列表,即x::xs是列表的头元素,xxs分别是它的头和尾。

你想要的是匹配列表前面的两个元素 - 你需要删除括号:

match list with
| a::b::tail ->

请注意,您使用的命名约定已经有一个提示 - xs 中的 s 表示复数 - 因此在该模式中,您将列表拆分为“ex”的头部和尾部“前任”。

【讨论】:

  • 非常感谢!这很有帮助!我还有一个问题是我如何才能让我的 reduce 函数采用任何类型?由于我将 int 0 作为初始累加器传递,因此结果将始终是一些 int,但是假设我想对其他类型(例如字符串或字符)执行 reduce 函数?有没有办法制作通用累加器?再次感谢
  • 这就是我的其他评论的内容 - 通常 reduce 不需要这个明确的初始值,并且预计会因空输入而失败。您可以使这个初始值显式并将其转换为函数的参数,但此时您实际上是在实现fold
猜你喜欢
  • 2015-08-31
  • 1970-01-01
  • 2020-05-02
  • 2021-07-17
  • 1970-01-01
  • 2022-01-16
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多