Module

Package
purescript-tailrec
Repository
purescript/purescript-tailrec

### #StepSource

``data Step a b``

The result of a computation: either `Loop` containing the updated accumulator, or `Done` containing the final result of the computation.

#### Constructors

• `Loop a`
• `Done b`

#### Instances

• `Functor (Step a)`
• `Bifunctor Step`

``class (Monad m) <= MonadRec m  where``

This type class captures those monads which support tail recursion in constant stack space.

The `tailRecM` function takes a step function, and applies that step function recursively until a pure value of type `b` is found.

Instances are provided for standard monad transformers.

For example:

``````loopWriter :: Int -> WriterT (Additive Int) Effect Unit
loopWriter n = tailRecM go n
where
go 0 = do
traceM "Done!"
pure (Done unit)
go i = do
pure (Loop (i - 1))
``````

#### Members

• `tailRecM :: forall a b. (a -> m (Step a b)) -> a -> m b`

#### Instances

• `MonadRec Identity`
• `MonadRec Effect`
• `MonadRec (Function e)`
• `MonadRec (Either e)`
• `MonadRec Maybe`

### #tailRecSource

``tailRec :: forall a b. (a -> Step a b) -> a -> b``

Create a pure tail-recursive function of one argument

For example:

``````pow :: Int -> Int -> Int
pow n p = tailRec go { accum: 1, power: p }
where
go :: _ -> Step _ Int
go { accum: acc, power: 0 } = Done acc
go { accum: acc, power: p } = Loop { accum: acc * n, power: p - 1 }
``````

### #tailRecM2Source

``tailRecM2 :: forall m a b c. MonadRec m => (a -> b -> m (Step { a :: a, b :: b } c)) -> a -> b -> m c``

Create a tail-recursive function of two arguments which uses constant stack space.

### #tailRecM3Source

``tailRecM3 :: forall m a b c d. MonadRec m => (a -> b -> c -> m (Step { a :: a, b :: b, c :: c } d)) -> a -> b -> c -> m d``

Create a tail-recursive function of three arguments which uses constant stack space.

### #foreverSource

``forever :: forall m a b. MonadRec m => m a -> m b``

`forever` runs an action indefinitely, using the `MonadRec` instance to ensure constant stack usage.

For example:

``````main = forever \$ trace "Hello, World!"
``````

### #whileJustSource

``whileJust :: forall a m. Monoid a => MonadRec m => m (Maybe a) -> m a``

While supplied computation evaluates to `Just _`, it will be executed repeatedly and results will be combined using monoid instance.

### #untilJustSource

``untilJust :: forall a m. MonadRec m => m (Maybe a) -> m a``

Supplied computation will be executed repeatedly until it evaluates to `Just value` and then that `value` will be returned.