Nếu tôi hiểu đúng, scala.util.control.TailCalls có thể được sử dụng để tránh tràn ngăn xếp cho các chức năng không đuôi-đệ quy bằng cách sử dụng một tấm bạt lò xo. Ví dụ được đưa ra trong API là đơn giản:Cách sử dụng TailCalls?
import scala.util.control.TailCalls._
def isEven(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(true) else tailcall(isOdd(xs.tail))
def isOdd(xs: List[Int]): TailRec[Boolean] =
if (xs.isEmpty) done(false) else tailcall(isEven(xs.tail))
isEven((1 to 100000).toList).result
Tuy nhiên, trường hợp thú vị hơn là nếu bạn muốn làm một số hoạt động sau cuộc gọi recursve. Tôi nhận được triển khai giai thừa "ngây thơ" bằng cách nào đó chạy bằng cách
def fac(n:Long): TailRec[Long] =
if (n == 0) done(1) else done(n * tailcall(fac(n - 1)).result)
nhưng điều này có vẻ khủng khiếp và tôi nghi ngờ rằng đây là mục đích sử dụng. Vì vậy, câu hỏi của tôi là làm thế nào để viết một hàm giai thừa hoặc hàm một cách chính xác bằng cách sử dụng TailCalls (có, tôi biết làm thế nào để sử dụng accumulators để có được chúng đệ quy đuôi)? Hay là TailCalls không phù hợp với loại vấn đề này?
Khi bạn nói 'scala.util.control.TailCalls là một hack', bạn có thể xin nói thêm là để khi nó thích hợp để sử dụng không? –
"hack" không có nghĩa là perjoratively ở đây. TailCalls là hoàn toàn thích hợp để sử dụng để tránh tràn stack từ các cuộc gọi đệ quy lẫn nhau. –