它是使用递归的强大技术,因为它具有强大的可描述性。尾递归提供比普通递归更强大的计算,因为它将递归变为迭代。Continuation-Passing Style (CPS) 可以将大量循环代码更改为尾递归。Continuation Monad 提供递归语法,但本质上它是尾递归,也就是迭代。100000阶乘应该合理使用Continuation Monad。这是代码。
type ContinuationBuilder() =
member b.Bind(x, f) = fun k -> x (fun x -> f x k)
member b.Return x = fun k -> k x
member b.ReturnFrom x = x
(*
type ContinuationBuilder =
class
new : unit -> ContinuationBuilder
member Bind : x:(('d -> 'e) -> 'f) * f:('d -> 'g -> 'e) -> ('g -> 'f)
member Return : x:'b -> (('b -> 'c) -> 'c)
member ReturnFrom : x:'a -> 'a
end
*)
let cont = ContinuationBuilder()
//val cont : ContinuationBuilder
let fac n =
let rec loop n =
cont {
match n with
| n when n = 0I -> return 1I
| _ -> let! x = fun f -> f n
let! y = loop (n - 1I)
return x * y
}
loop n (fun x -> x)
let x2 = fac 100000I
出现错误消息:“由于 StackOverflowException 而终止进程。”
使用 ContinuationMonad 的 100000 阶乘有什么问题?