代码之家  ›  专栏  ›  技术社区  ›  clay

Scala中的尾部递归findNextAndTail

  •  0
  • clay  · 技术社区  · 7 年前

    我该怎么做 findNextAndTail 下尾递归?

      def uncons[A](s: Seq[A]): Option[(A, Seq[A])] = for (h <- s.headOption) yield (h, s.tail)
    
      // This works as-is. How can I make this function tail recursive?
      // @tailrec
      def findNextAndTail[A, B](parseFunction: A => Option[B], s: Seq[A]): Option[(B, Seq[A])] =
        for ((h, tail) <- uncons(s); r <- parseFunction(h) match {
          case Some(b) => Some((b, tail))
          case None => findNextAndTail(parseFunction, tail)
        }) yield r
    
      // Function for example usage
      def parseInt(s: String): Option[Int] = try {
        Some(Integer.parseInt(s))
      } catch {
        case _ => None
      }
    
      // Example usage of findNextAndTail
      def main(args: Array[String]): Unit = {
        val l = List("a", "b", "123", "x", "y", "z")
        val r = findNextAndTail(parseInt, l)
        // r=Some((123,List(x, y, z)))
        println(s"r=$r")
      }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   jwvh    7 年前

    试试这个。

    @annotation.tailrec
    def findNextAndTail[A, B](parseFunction: A => Option[B]
                             ,s: Seq[A]): Option[(B, Seq[A])] =
      uncons(s) match {
        case Some((h, tail)) =>
          parseFunction(h) match {
            case Some(b) => Some((b, tail))
            case None => findNextAndTail(parseFunction, tail)
          }
        case _ => None
      }