現在Functional Programming in Scalaの日本語訳を読んでいます。exercise 4.5のtraverse関数を実装せよという問題に関しての質問です。

def traverse[A,B](as:List[A])(f:A=>Option[B]):Option[List[B]]= as match{
 | case Nil => Some(Nil)
 | case (h::t) => for{
 | hh <- f(h)
 | tt <- traverse(t)(f)
 | } yield(hh::tt)
 | }

 traverse: [A, B](as: List[A])(f: A => Option[B])Option[List[B]]

この関数は正常に動くようですが、

traverse((1 to 10000).toList)(i => Some(i))

と長さが一万程度のlistでstackoverflowになってしまいます。
flatMap内で再帰しているので末尾再帰にできません。
flatMapで再帰する関数でstacksafeにするにはどのようにすればいいでしょうか。