lam*_*das 11 functional-programming scala
我正在向远程服务器发出请求,有时由于网络不可靠而请求失败.如果失败我想要重复请求,但n最多时间.如果我使用命令式语言,我会将请求发送代码放在while循环中,但我想以功能方式进行.
我为此目的写了一个帮手:
/** Repeatedly executes function `f`
* while predicate `p` holds
* but no more than `nTries` times.
*/
def repeatWhile[A](f: => A)(p: A => Boolean)(nTries: Int): Option[A] =
if (nTries == 0) {
None
} else {
f match {
case a if p(a) => repeatWhile(f)(p)(nTries - 1)
case a => Some(a)
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它像这样:
// Emulating unreliable connection
var n = 0
def receive(): Option[String] =
if (n < 4) {
n += 1
println("No result...")
None
} else {
println("Result!")
Some("Result")
}
// Repeated call
val result = repeatWhile(receive)(!_.isDefined)(10)
Run Code Online (Sandbox Code Playgroud)
哪里receive是用于测试目的的愚蠢功能.此代码在receive最终成功之前进行4次调用Some(Result):
No result...
No result...
No result...
No result...
Result!
Run Code Online (Sandbox Code Playgroud)
我的repeatWhile工作很好,但我觉得要重新发明轮子.我正在学习函数式编程,想知道我的问题是否有简单/标准的解决方案.
Ps我已经定义了更多的助手,也许他们已经在语言/标准库中?
/** Repeatedly executes function `f`
* while predicated `p` not holds
* but no more than `nTries` times.
*/
def repeatWhileNot[A](f: => A)(p: A => Boolean)(nTries:Int): Option[A] =
repeatWhile(f)(!p(_))(nTries)
/** Repeatedly executes function `f`
* while it returns None
* but no more than `nTries` times.
*/
def repeatWhileNone[A](f: => Option[A])(nTries:Int): Option[A] =
repeatWhileNot(f)(_.isDefined)(nTries).getOrElse(None)
Run Code Online (Sandbox Code Playgroud)
Rex*_*err 15
规范的方法是使用Iterator:
Iterator.continually{f}.take(nTries).dropWhile(!p).take(1).toList
Run Code Online (Sandbox Code Playgroud)
这将为您提供一个空列表或一个项目列表,具体取决于它是否成功.headOption如果您愿意,可以将其转换为选项.经过微小的修改,这适用于您的所有用例.
尽管它们不在库中,但是如你所做的那样编写小的递归方法也是非常明智的.一般来说,为你最常做的事情编写辅助方法是一个非常好的主意.这就是Scala使编写方法变得如此简单的原因之一.
| 归档时间: |
|
| 查看次数: |
1138 次 |
| 最近记录: |