# Contstuff

### From HaskellWiki

(Difference between revisions)

m (→Introduction: Fixed wiki markup typo.) |
(Added a lot of stuff.) |

## Revision as of 23:49, 20 September 2010

## Contents |

## 1 Introduction

The contstuff library implements a number of monad transformers and monads, which make heavy use of continuation passing style (CPS). This makes them both fast and flexible. Please note that this is neither a CPS tutorial nor a monad transformer tutorial. You should understand these concepts, before attempting to use *contstuff*.

## 2 Basics

### 2.1 ContT

TheContT

- abortion (premature termination),
- resumption (start a computation at a certain spot),
- branches (aka
*goto*), - result accumulation,
- etc.

ContT

ContT

ContT r m a

a

r

r

abort

ContT

runContT

evalContT

runContT :: (a -> m r) -> ContT r m a -> m r evalContT :: Applicative m => ContT r m r -> m r

runContT

evalContT

pure

### 2.2 Abortion

Let's have a look at a small example:

testComp1 :: ContT () IO () testComp1 = forever $ do txt <- io getLine case txt of "info" -> io $ putStrLn "This is a test computation." "quit" -> abort () _ -> return ()

ContT

ContT

io

liftIO

inBase

IO

base

ContT

ContT

abort

### 2.3 Resumption and branches

You can capture the current continuation using the commoncallCC

labelCC :: a -> ContT r m (a, Label (ContT r m) a) goto :: Label (ContT r m) a -> a -> ContT r m b

These slightly complicated looking functions are actually very simple to use:

testComp2 :: ContT r IO () testComp2 = do (i, again) <- labelCC 0 io (print i) when (i < 10) $ goto again (i+1) io (putStrLn $ "Final result: " ++ show i)

labelCC

goto

labelCC

i

goto

i

labelCC

ContT

### 2.4 Lifting

As noted earlier there are three lifting functions, which you can use to access monads in lower layers of the transformer stack:

lift :: (Transformer t, Monad m) => m a -> t m a base :: (LiftBase m a) => Base m a -> m a io :: (Base m a ~ IO a, LiftBase m a) => Base m a -> m a

lift

base

liftIO

io

base

IO

### 2.5 Accumulating results

ContT

Alternative

(<|>)

m

Alternative

ContT r m

testComp3 :: Num a => ContT r [] (a, a) testComp3 = do x <- pure 10 <|> pure 20 y <- pure (x+1) <|> pure (x-1) return (x, y)

*contstuff*library implements a convenience function

listA

Alternative

listA :: (Alternative f) => [a] -> f a

testComp3

testComp3' :: Num a => ContT r [] (a, a) testComp3' = do x <- listA [10, 20] y <- listA [x+1, x-1] return (x, y)

abort

testComp4 :: Num a => ContT (a, a) [] (a, a) testComp4 = do x <- listA [10, 20] when (x == 10) (abort (10, 10)) y <- listA [x+1, x-1] return (x, y)