0 | ||| The simplest stack-safe monadic evaluation
7 | ||| The simplest monad of stack-safe pure computations
8 | |||
9 | ||| This is effectively an `Identity` monad with stack-safe implementations
10 | ||| of standard combinators.
11 | |||
12 | ||| It can be used as a simplest transformation of a pure functional
13 | ||| non-stack-safe code to stack-safe one with minimal changes in code.
14 | |||
15 | ||| For example, consider the tree data type example and ordinary
16 | ||| non-stack-safe implementation of `Functor` for it:
17 | |||
18 | ||| ```idris
19 | ||| data Tree a = Leaf a | Node a (List1 (Tree a))
20 | |||
21 | ||| Functor Tree where
22 | ||| map f (Leaf x) = Leaf $ f x
23 | ||| map f (Node x xs) = Node (f x) $ map @{Compose} f xs
24 | ||| ```
25 | |||
26 | ||| Using the `Eval` monad, you can turn it do a stack-safe one
27 | |||
28 | ||| ```idris
29 | ||| Functor Tree where
30 | ||| map f = eval . go where
31 | ||| go : Tree a -> Eval $ Tree b
32 | ||| go (Leaf x) = pure $ Leaf $ f x
33 | ||| go (Node x xs) = defer $ Node (f x) <$> traverse go xs
34 | |||
35 | ||| ```
36 | export
45 | ||| Suspends a lazy evaluation into the `Eval` monad
46 | |||
47 | ||| This can be used to suspend the recursive calls, or the whole expressions
48 | ||| containing the recursive calls, in order to provide stack-safety
66 | -- This implementation is indeed tail-recursive because it solely calls
67 | -- a constructor and the recursive call is suspended in a function
68 | export
74 | export
82 | covering