#Step Source

data Step a b

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



#MonadRec Source

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 :: Number -> WriterT Sum (Eff (trace :: Trace)) Unit
loopWriter n = tailRecM go n
  go 0 = do
    lift $ trace "Done!"
    pure (Done unit)
  go n = do
    tell $ Sum n
    pure (Loop (n - 1))



#tailRecM2 Source

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.

#tailRecM3 Source

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.

#tailRec Source

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

Create a pure tail-recursive function of one argument

For example:

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

#forever Source

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!"