1

I'm trying to pause a computation and later resume it on demand (upon a prompt from the user). It should resemble something like the following, only using the continuation monad.

import Control.Monad.IO.Class (liftIO,MonadIO(..))
import Data.Void

f :: MonadIO m => Int -> Int -> m Void
f x y = do
  liftIO (print x)
  input <- liftIO getLine
  if input /= "pause"
     then (f (x+1) y)
     else (f' y x)

f' :: MonadIO m => Int -> Int -> m Void
f' x y = do
  liftIO (print x)
  input <- liftIO getLine
  if input /= "pause"
     then (f' (x-1) y)
     else (f y x)

Example output:

λ> f 5 5
5

6

7

8
pause
5

4

3

2
pause
8

9

10
Interrupted.

Original version of the question:

-- Helpers
cond = fmap (not . (== "pause")) getLine
ch b x y = if b then x else y
ch' :: a -> a -> Bool -> a
ch' = flip . (flip ch)

-- Main code
f i i' = liftIO (print i) >> liftIO cond >>= ch' (f (i+1) i') (f' i'  i)
f' i i' = liftIO (print i) >> liftIO cond >>= ch' (f' (i-1) i') (f i' i)
Markus1189
  • 2,829
  • 1
  • 23
  • 32
  • 7
    You should really avoid extremes of point-free silliness (e.g., `ch'`), especially when you don't know what your code will ultimately look like and especially when you want other people to help. If you really like, you can use the standard function `bool`, which is similar but readily recognized as the `Bool` eliminator. Note also: `not . (== "pause")` is better written `(/= "pause")`. – dfeuer Sep 22 '15 at 03:35
  • 1
    Maybe something like this? http://stackoverflow.com/questions/10236953/the-pause-monad – MathematicalOrchid Sep 22 '15 at 08:11

0 Answers0