@@ -0,0 +1,42 @@
1+module Trampoline where
3+{-| Trampolining loops for unbounded recursion.
4+Since most javascript implementations lack tail-call elimination, deeply tail-recursive functions will result in a stack overflow.
7+fac' : Int -> Int -> Int
10+ else fac' (n - 1) (n * acc)
16+main = asText <| fac 1000000000000
19+Trampolining allows for long-running tail-recursive loops to be run without pushing calls onto the stack:
21+facT : Int -> Int -> Trampoline Int
22+facT n acc = if n <= 0
24+ else Continue <| \() -> facT (n - 1) (n * acc)
26+fac n = trampoline <| facT n 0
28+-- Doesn't stack overflow
29+main = asText <| fac 1000000000000
32+@docs Trampoline, trampoline
34+import Native.Trampoline
36+{-| A computation that might loop. A trampoline is either the resulting value or a thunk that needs to be run more. -}
37+data Trampoline a = Done a
38+ | Continue (() -> Trampoline a)
40+{-| Run a trampolining loop in constant space. -}
41+trampoline : Trampoline a -> a
42+trampoline = Native.Trampoline.trampoline