FoldLeft在Scala中使用FoldRight
经过
Functional Programming in Scala,我遇到这个问题:
在作者提供的解决方案中,他们提供了如下实现: 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) 按要求。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |