Cal*_*oiu 9 functional-programming scala
我经常遇到一个模式,所以我想知道Scala库中是否有任何方便的方法.
让它成为一种功能f: A => Option[B].我愿做一个反复调用f一个起点开始x,f(f(f(x).get).get...)直至f恢复None并保持最后的非None价值.
我为此写了一个实现:
@tailrec
def recurrentCallUntilNone[B](f: B => Option[B], x: B): B = f(x) match {
case Some(y) => recurrentCallUntilNone(f, y)
case None => x
}
Run Code Online (Sandbox Code Playgroud)
这已经在标准库中实现了吗?
对此的使用示例可以是用于保持当前位置的列表(Zipper).通过调用next,None如果在当前位置之后没有元素或者Option对于相同列表没有元素但是当前位置递增,则返回.通过使用上述方法,end可以构造一种寻找列表到最后的方法.
你正在做的事情看起来像是一种非常特殊类型的蹦床。更一般的情况使用包装在案例类中的函数而不是 anOption并支持不同的参数和返回类型。
正如 Calin-Andrei 指出的那样,标准库中可以使用TailCalls 对象来使用蹦床。
从第一个链接:
def even2(n: Int): Bounce[Boolean] = {
if (n == 0) Done(true)
else Call(() => odd2(n - 1))
}
def odd2(n: Int): Bounce[Boolean] = {
if (n == 0) Done(false)
else Call(() => even2(n - 1))
}
trampoline(even2(9999))
sealed trait Bounce[A]
case class Done[A](result: A) extends Bounce[A]
case class Call[A](thunk: () => Bounce[A]) extends Bounce[A]
def trampoline[A](bounce: Bounce[A]): A = bounce match {
case Call(thunk) => trampoline(thunk())
case Done(x) => x
}
Run Code Online (Sandbox Code Playgroud)
现在有了标准库
import scala.util.control.TailCalls._
def even2(n: Int): TailRec[Boolean] = {
if (n == 0) done(true)
else tailcall(odd2(n - 1))
}
def odd2(n: Int): TailRec[Boolean] = {
if (n == 0) done(false)
else tailcall(even2(n - 1))
}
even2(9999).result
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
412 次 |
| 最近记录: |