2017-09-02 81 views
0

如何使尾部遞歸下的findNextAndTailScala中的尾遞歸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") 
    } 

回答

0

試試看。

@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 
    }