加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

FoldLeft在Scala中使用FoldRight

发布时间:2020-12-16 09:43:01 所属栏目:安全 来源:网络整理
导读:经过 Functional Programming in Scala,我遇到这个问题: Can you right foldLeft in terms of foldRight? How about the other way around? 在作者提供的解决方案中,他们提供了如下实现: def foldRightViaFoldLeft_1[A,B](l: List[A],z: B)(f: (A,B) = B
经过 Functional Programming in Scala,我遇到这个问题:

Can you right foldLeft in terms of foldRight? How about the other way
around?

在作者提供的解决方案中,他们提供了如下实现:

def foldRightViaFoldLeft_1[A,B](l: List[A],z: B)(f: (A,B) => B): B = 
    foldLeft(l,(b:B) => b)((g,a) => b => g(f(a,b)))(z)

  def foldLeftViaFoldRight[A,z: B)(f: (B,A) => B): B = 
    foldRight(l,(b:B) => b)((a,g) => b => g(f(b,a)))(z)

有人可以帮助我追踪这个解决方案,让我明白这个实际上是如何实现折叠的,而反之亦然呢?

谢谢

解决方法

让我们来看看

def foldLeftViaFoldRight[A,A) => B): B = 
  foldRight(l,a)))(z)

(另一个折叠是相似的)。诀窍在于,在正确的折叠操作中,我们不构建类型B的最终值。相反,我们从B到B构建一个函数。折叠步骤的值为a:A和函数g:B => B并产生新的函数(b => g(f(b,a))):B => B.这个函数可以用f(_,a)表示为g的组合:

l.foldRight(identity _)((a,g) => g compose (b => f(b,a)))(z);

我们可以查看过程如下:对于l的每个元素,我们采用部分应用程序b => f(b,a),其为函数B =>那么,我们compose所有这些功能都是这样一种方式,使得对应于最右边元素(我们开始遍历)的函数在组合链中最左边。最后,我们在z上应用大组合函数。这将导致一系列操作从最左边的元素(组成链中最右边的元素)开始,并以最右边的元素完成。

更新:作为一个例子,我们来看看这个定义如何在一个两元素列表上工作。首先,我们将重写函数

def foldLeftViaFoldRight[A,z: B)
                             (f: (B,A) => B): B =
{
  def h(a: A,g: B => B): (B => B) =
    g compose ((x: B) => f(x,a));
  l.foldRight(identity[B] _)(h _)(z);
}

现在我们来计算当我们通过它会发生什么List(1,2):

List(1,2).foldRight(identity[B] _)(h _)
  = // by the definition of the right fold
h(1,h(2,identity([B])))
  = // expand the inner `h`
h(1,identity[B] compose ((x: B) => f(x,2)))
  =
h(1,((x: B) => f(x,2)))
  = // expand the other `h`
((x: B) => f(x,2)) compose ((x: B) => f(x,1))
  = // by the definition of function composition
(y: B) => f(f(y,1),2)

将此函数应用于z产生

f(f(z,2)

按要求。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读