一般来说,在“内部”单子中工作时,我很难弄清楚如何编写尾递归函数。这是一个简单的例子:
这是来自我正在编写的一个小型示例应用程序,以更好地理解 Scala 中的 FP。首先提示用户输入一个Team
由 7Player
秒组成的。这个函数递归地读取输入:
import cats.effect.{ExitCode, IO, IOApp}
import cats.implicits._
case class Player (name: String)
case class Team (players: List[Player])
/**
* Reads a team of 7 players from the command line.
* @return
*/
def readTeam: IO[Team] = {
def go(team: Team): IO[Team] = { // here I'd like to add @tailrec
if(team.players.size >= 7){
IO(println("Enough players!!")) >>= (_ => IO(team))
} else {
for {
player <- readPlayer
team <- go(Team(team.players :+ player))
} yield team
}
}
go(Team(Nil))
}
private def readPlayer: IO[Player] = ???
现在我想要实现的(主要用于教育目的)是能够@tailrec
在def go(team: Team)
. 但是我不认为有可能将递归调用作为我的最后一个语句,因为据我所知,最后一个语句总是必须将我的“提升”Team
到 IO 单子中。
任何提示将不胜感激。