@@ -1,11 +1,43 @@
11module Trampoline (Trampoline, trampoline)
22 where
33
4−{-| -}
4+{-| Trampolining loops for unbounded recursion.
5+Since most javascript implementations lack tail-call elimination, deeply tail-recursive functions will result in a stack overflow.
6+
7+```haskell
8+fac' : Int -> Int -> Int
9+fac' n acc = if n <= 0
10+ then acc
11+ else fac' (n - 1) (n * acc)
12+
13+fac : Int -> Int
14+fac n = fac' n 1
15+
16+-- Stack overflow
17+main = asText <| fac 1000000000000
18+```
19+
20+Trampolining allows for long-running tail-recursive loops to be run without pushing calls onto the stack:
21+```haskell
22+facT : Int -> Int -> Trampoline Int
23+facT n acc = Trampoline <| if n <= 0
24+ then Left acc
25+ else Right <| \() -> facT (n - 1) (n * acc)
26+fac : Int -> Int
27+fac n = trampoline <| facT n 0
28+
29+-- Doesn't stack overflow
30+main = asText <| fac 1000000000000
31+```
32+# Trampoline
33+@docs Trampoline, trampoline
34+ -}
535import Native.Trampoline
636import open Either
737
38+{-| A computation that might loop. A trampoline is either the resulting value or a thunk that needs to be run more. -}
839data Trampoline a = Trampoline (Either a (() -> Trampoline a))
940
41+{-| Run a trampolining loop in constant space. -}
1042trampoline : Trampoline a -> a
1143trampoline = Native.Trampoline.trampoline