gpt4 book ai didi

scala - 重复调用函数,直到返回 None

转载 作者:行者123 更新时间:2023-12-03 04:34:24 26 4
gpt4 key购买 nike

我经常遇到一种模式,所以我想知道Scala库中是否有任何方便的方法。

让它成为一个函数f: A => Option[B]。我想对以 x 开头的 f 进行循环调用,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
}

这已经在标准库中实现了吗?

一个使用示例可以是保持当前位置的列表(Zipper)。通过调用 next,如果当前位置之后没有元素,则返回 None,或者同一列表的 Option,但当前位置递增。通过使用上述方法,可以构造一个 end 方法来查找列表的末尾。

最佳答案

您正在做的事情看起来像是一种非常具体的 trampoline 类型。更一般的情况使用案例类中包装的函数而不是 Option 并支持不同的参数和返回类型。

Calin-Andrei 指出,标准库中可以使用 TailCalls object 来使用蹦床。 .

从第一个链接:

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
}

现在有了标准库

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

关于scala - 重复调用函数,直到返回 None,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15706788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com