turtle-1.3.1: Shell programming, Haskell-style

Safe Haskell | Safe
Language | Haskell2010

Turtle.Shell

Contents

- Shell
- Embeddings

Description

You can think of `Shell` as `[]` + `IO` + `Managed`. In fact, you can embed all three of them within a `Shell`:

    select ::        [a] -> Shell a
    liftIO ::      IO a  -> Shell a
    using  :: Managed a  -> Shell a

Those three embeddings obey these laws:

    do { x <- select m; select (f x) } = select (do { x <- m; f x })
    do { x <- liftIO m; liftIO (f x) } = liftIO (do { x <- m; f x })
    do { x <- with   m; using  (f x) } = using  (do { x <- m; f x })

    select (return x) = return x
    liftIO (return x) = return x
    using  (return x) = return x

... and `select` obeys these additional laws:

    select xs <|> select ys = select (xs <|> ys)
    select empty = empty

You typically won't build `Shell`s using the `Shell` constructor. Instead, use these functions to generate primitive `Shell`s:

- `empty`, to create a `Shell` that outputs nothing
- `return`, to create a `Shell` that outputs a single value
- `select`, to range over a list of values within a `Shell`
- `liftIO`, to embed an `IO` action within a `Shell`
- `using`, to acquire a `Managed` resource within a `Shell`

Then use these classes to combine those primitive `Shell`s into larger `Shell`s:

- `Alternative`, to concatenate `Shell` outputs using (`<|>`)
- `Monad`, to build `Shell` comprehensions using `do` notation

If you still insist on building your own `Shell` from scratch, then the `Shell` you build must satisfy this law:

    -- For every shell `s`:
    _foldIO s (FoldM step begin done) = do
        x  <- begin
        x' <- _foldIO s (FoldM step (return x) return)
        done x'

... which is a fancy way of saying that your `Shell` must call `'begin'` exactly once when it begins and call `'done'` exactly once when it ends.

Synopsis

- newtype Shell a = Shell {
  - _foldIO :: forall r. FoldM IO a r -> IO r
  }
- foldIO :: MonadIO io => Shell a -> FoldM IO a r -> io r
- fold :: MonadIO io => Shell a -> Fold a b -> io b
- sh :: MonadIO io => Shell a -> io ()
- view :: (MonadIO io, Show a) => Shell a -> io ()
- select :: [a] -> Shell a
- liftIO :: MonadIO m => forall a. IO a -> m a
- using :: MonadManaged m => forall a. Managed a -> m a

# Shell

newtype Shell a #

A `(Shell a)` is a protected stream of `a`'s with side effects

Constructors

Shell |
Fields _foldIO :: forall r. FoldM IO a r -> IO r

Instances

Monad Shell # |
Methods (>>=) :: Shell a -> (a -> Shell b) -> Shell b # (>>) :: Shell a -> Shell b -> Shell b # return :: a -> Shell a # fail :: String -> Shell a #
Functor Shell # |
Methods fmap :: (a -> b) -> Shell a -> Shell b # (<$) :: a -> Shell b -> Shell a #
Applicative Shell # |
Methods pure :: a -> Shell a # (<*>) :: Shell (a -> b) -> Shell a -> Shell b # (*>) :: Shell a -> Shell b -> Shell b # (<*) :: Shell a -> Shell b -> Shell a #
MonadIO Shell # |
Methods liftIO :: IO a -> Shell a #
Alternative Shell # |
Methods empty :: Shell a # (<|>) :: Shell a -> Shell a -> Shell a # some :: Shell a -> Shell [a] # many :: Shell a -> Shell [a] #
MonadPlus Shell # |
Methods mzero :: Shell a # mplus :: Shell a -> Shell a -> Shell a #
MonadManaged Shell # |
Methods using :: Managed a -> Shell a #
Monoid a => Num (Shell a) # | Shell forms a semiring, this is the closest approximation
Methods (+) :: Shell a -> Shell a -> Shell a # (-) :: Shell a -> Shell a -> Shell a # (*) :: Shell a -> Shell a -> Shell a # negate :: Shell a -> Shell a # abs :: Shell a -> Shell a # signum :: Shell a -> Shell a # fromInteger :: Integer -> Shell a #
IsString a => IsString (Shell a) # |
Methods fromString :: String -> Shell a #
Monoid a => Monoid (Shell a) # |
Methods mempty :: Shell a # mappend :: Shell a -> Shell a -> Shell a # mconcat :: [Shell a] -> Shell a #

foldIO :: MonadIO io => Shell a -> FoldM IO a r -> io r #

Use a ``FoldM` `IO`` to reduce the stream of `a`'s produced by a `Shell`

fold :: MonadIO io => Shell a -> Fold a b -> io b #

Use a `Fold` to reduce the stream of `a`'s produced by a `Shell`

sh :: MonadIO io => Shell a -> io () #

Run a `Shell` to completion, discarding any unused values

view :: (MonadIO io, Show a) => Shell a -> io () #

Run a `Shell` to completion, `print`ing any unused values

# Embeddings

select :: [a] -> Shell a #

Convert a list to a `Shell` that emits each element of the list

liftIO :: MonadIO m => forall a. IO a -> m a #

Lift a computation from the `IO` monad.

using :: MonadManaged m => forall a. Managed a -> m a #