在Scala中的Corecursion vs递归理解
发布时间:2020-12-16 18:22:59 所属栏目:安全 来源:网络整理
导读:例如,如果递归几乎清楚 def product2(ints: List[Int]): Int = { @tailrec def productAccumulator(ints: List[Int],accum: Int): Int = { ints match { case Nil = accum case x :: tail = productAccumulator(tail,accum * x) } } productAccumulator(ints
例如,如果递归几乎清楚
def product2(ints: List[Int]): Int = { @tailrec def productAccumulator(ints: List[Int],accum: Int): Int = { ints match { case Nil => accum case x :: tail => productAccumulator(tail,accum * x) } } productAccumulator(ints,1) } 我不确定核心运行.根据Wikipedia article,“corecursion允许程序产生任意复杂且可能无限的数据结构,例如流”.例如这样的构造 list.filter(...).map(...) 在过滤和映射操作之后使临时流准备好. 功能组合器是否使用递归执行来进行地图过滤 解决方法
理解差异的最简单方法是认为递归消耗数据,而corecursion产生数据.您的示例是递归,因为它使用您作为参数提供的列表.另外,foldLeft和foldRight也是递归,而不是corecursion.现在是一个corecursion的例子.考虑以下功能:
def unfold[A,S](z: S)(f: S => Option[(A,S)]): Stream[A] 只需查看其签名,您就可以看到此函数旨在生成无限的数据流.它采用初始状态,类型S的z,以及从S到可能元组的函数,该元组将包含下一个状态和流的实际值,即类型A.如果f的结果为空(无)然后展开停止生成元素,否则它继续通过下一个状态,依此类推.这是它的实现: def unfold[S,A](z: S)(f: S => Option[(A,S)]): Stream[A] = f(z) match { case Some((a,s)) => a #:: unfold(s)(f) case None => Stream.empty[A] } 您可以使用此功能实现其他生产功能.例如.以下函数将生成一个最多为A类型的numOfValues元素的流: def elements[A](element: A,numOfValues: Int): Stream[A] = unfold(numOfValues) { x => if (x > 0) Some((element,x - 1)) else None } REPL中的用法示例: scala> elements("hello",3) res10: Stream[String] = Stream(hello,?) scala> res10.toList res11: List[String] = List(hello,hello,hello) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |