微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Scala中的Corecursion vs递归理解

例如,如果递归几乎清楚

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(...)

在过滤和映射操作之后使临时流准备好.
过滤器流之后将只收集过滤后的元素,然后在地图中我们将更改元素.正确?

功能组合器是否使用递归执行来进行地图过滤
Scala中有没有一个很好的例子“比较递归和核心运算”?

解决方法

理解差异的最简单方法是认为递归消耗数据,而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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐