Maintainer | joeyadams3.14159@gmail.com |
---|---|

Safe Haskell | Safe-Infered |

- newtype LoopT c e m a = LoopT {
- runLoopT :: forall r. (c -> m r) -> (e -> m r) -> (a -> m r) -> m r

- stepLoopT :: Monad m => LoopT c e m c -> (c -> m e) -> m e
- continue :: LoopT () e m a
- exit :: LoopT c () m a
- continueWith :: c -> LoopT c e m a
- exitWith :: e -> LoopT c e m a
- foreach :: Monad m => [a] -> (a -> LoopT c () m c) -> m ()
- while :: Monad m => m Bool -> LoopT c () m c -> m ()
- doWhile :: Monad m => LoopT a a m a -> m Bool -> m a
- once :: Monad m => LoopT a a m a -> m a
- repeatLoopT :: Monad m => LoopT c e m a -> m e
- iterateLoopT :: Monad m => c -> (c -> LoopT c e m c) -> m e
- liftLocalLoopT :: Monad m => (forall a. m a -> m a) -> LoopT c e m b -> LoopT c e m b

# The LoopT monad transformer

`LoopT`

is a monad transformer for the loop body. It provides two
capabilities:

stepLoopT :: Monad m => LoopT c e m c -> (c -> m e) -> m eSource

Call a loop body, passing it a continuation for the next iteration.
This can be used to construct custom looping constructs. For example,
here is the definition of `foreach`

:

foreach list body = loop list where loop [] = return () loop (x:xs) = stepLoopT (body x) (\_ -> loop xs)

# continue and exit

continueWith :: c -> LoopT c e m aSource

Like `continue`

, but return a value from the loop body.

exitWith :: e -> LoopT c e m aSource

Like `exit`

, but return a value from the loop as a whole.
See the documentation of `iterateLoopT`

for an example.

# Looping constructs

while :: Monad m => m Bool -> LoopT c () m c -> m ()Source

Repeat the loop body while the predicate holds. Like a `while`

loop in C,
the condition is tested first.

repeatLoopT :: Monad m => LoopT c e m a -> m eSource

Execute the loop body again and again. The only way to exit `repeatLoopT`

is to call `exit`

or `exitWith`

.

iterateLoopT :: Monad m => c -> (c -> LoopT c e m c) -> m eSource

Call the loop body again and again, passing it the result of the previous
iteration each time around. The only way to exit `iterateLoopT`

is to call
`exit`

or `exitWith`

.

Example:

count :: Int -> IO Int count n = iterateLoopT 0 $ \i -> if i < n then do lift $ print i return $ i+1 else exitWith i