İşte fs2 belgelerinden bir parça kod . İşlev goözyinelemeli. Soru, yığının güvenli olup olmadığını nasıl bilebiliriz ve herhangi bir fonksiyonun yığın güvenli olup olmadığını nasıl anlayabiliriz?
import fs2._
// import fs2._
def tk[F[_],O](n: Long): Pipe[F,O,O] = {
def go(s: Stream[F,O], n: Long): Pull[F,O,Unit] = {
s.pull.uncons.flatMap {
case Some((hd,tl)) =>
hd.size match {
case m if m <= n => Pull.output(hd) >> go(tl, n - m)
case m => Pull.output(hd.take(n.toInt)) >> Pull.done
}
case None => Pull.done
}
}
in => go(in,n).stream
}
// tk: [F[_], O](n: Long)fs2.Pipe[F,O,O]
Stream(1,2,3,4).through(tk(2)).toList
// res33: List[Int] = List(1, 2)
goBaşka bir yöntemden çağırırsak da yığın güvenli olur mu?
def tk[F[_],O](n: Long): Pipe[F,O,O] = {
def go(s: Stream[F,O], n: Long): Pull[F,O,Unit] = {
s.pull.uncons.flatMap {
case Some((hd,tl)) =>
hd.size match {
case m if m <= n => otherMethod(...)
case m => Pull.output(hd.take(n.toInt)) >> Pull.done
}
case None => Pull.done
}
}
def otherMethod(...) = {
Pull.output(hd) >> go(tl, n - m)
}
in => go(in,n).stream
}
goÖrneğin Monad[F]typeclass'ı kullanmak için yeniden yazabilirsiniz - tailRecMişlevin istif güvenli olacağından emin olmak için trambolini açıkça gerçekleştirmenizi sağlayan bir yöntem vardır . Yanılıyor olabilirim ama onsuz Fkendi başına güvenli bir şekilde istiflenmeye güveniyorsunuz (örneğin, trambolini dahili olarak uygularsa), ancak kiminizi tanımlayacağını asla bilemezsiniz F, bu yüzden bunu yapmamalısınız. FYığın güvenliği için bir garantiniz yoksa, tailRecMyasalar tarafından yığın açısından güvenli olduğu için bir tür sınıfı kullanın .
@tailreckuyruk kayıt işlevleri için ek açıklama ile kanıtlamasına izin vermek kolaydır . Diğer durumlar için Scala AFAIK'te resmi bir garanti yoktur. Fonksiyonun kendisi güvenli olsa bile, çağırdığı diğer fonksiyonlar olmayabilir: /.