Safe Haskell | Safe-Infered |
---|

Simplify static Networking tasks.

- data NetSpec t s
- data SpecState s
- runSpec :: Traversable t => NetSpec t s -> IO ()
- continue :: Monad m => s -> m (SpecState s)
- continue_ :: Monad m => m (SpecState ())
- continueIf :: Monad m => (a -> s -> Bool) -> m (a, s) -> m (SpecState s)
- continueIf' :: Monad m => (s -> Bool) -> m s -> m (SpecState s)
- continueIf_ :: Monad m => (a -> Bool) -> m a -> m (SpecState ())
- stop :: Monad m => s -> m (SpecState s)
- stop_ :: Monad m => m (SpecState ())
- stopIf :: Monad m => (a -> s -> Bool) -> m (a, s) -> m (SpecState s)
- stopIf' :: Monad m => (s -> Bool) -> m s -> m (SpecState s)
- stopIf_ :: Monad m => (a -> Bool) -> m a -> m (SpecState ())
- (.:) :: (a -> b) -> (c -> d -> a) -> c -> d -> b
- stateT :: Monad m => (s -> (a, s)) -> StateT s m a

# Types and Constructors

Define the specification of your networking task
as a begin, loop, and end proceedure. Run your NetSpec
with `runSpec`

.

`t`

indicates the `Traversable`

structure used.
`[]`

is recommended for simplicity, but you are at liberty
to use any Traversable you see fit.

`s`

indicates the type used for state.
Use `()`

for a stateless specification.

A server must specify which ports to listen on, while a client instead specifies tuples of (hostname, port) to connect to.

Indicate whether to `Continue`

or `Stop`

with a given state

# Functions

## Running a NetSpec

runSpec :: Traversable t => NetSpec t s -> IO ()Source

Run a `NetSpec`

.

Running a spec will step through your `Traversable`

of connection descriptions, and replace each one with a `Handle`

,
preserving the structure of the Traversable otherwise.

Regardless of exceptions, all Handles and Sockets opened by the spec will be closed at the end of the run; you should not need to close any of the Handles given to you by the spec.

(Note `runSpec`

calls `withSocketsDo`

for you)

## Continue and Stop Combinators

continueIf :: Monad m => (a -> s -> Bool) -> m (a, s) -> m (SpecState s)Source

Conditionally continue with a given state, based on that state and additional given information.

Recommended usage:

_loop = \handles -> continueIf f .: runStateT $ do ...

continueIf' :: Monad m => (s -> Bool) -> m s -> m (SpecState s)Source

Conditionally continue with a given state, based solely on that state.

Recommended usage:

_loop = \handles -> continueIf' f .: execStateT $ do ...

continueIf_ :: Monad m => (a -> Bool) -> m a -> m (SpecState ())Source

Conditionally continue statelessly, based on given information.

Recommended usage

_loop = \handles () -> continueIf_ f $ do ...

stopIf :: Monad m => (a -> s -> Bool) -> m (a, s) -> m (SpecState s)Source

Conditionally stop with a given state, based on that state and additional given information.

stopIf' :: Monad m => (s -> Bool) -> m s -> m (SpecState s)Source

Conditionally stop with a given state, based solely on that state.

stopIf_ :: Monad m => (a -> Bool) -> m a -> m (SpecState ())Source

Conditionally stop statlessly, based on given information.

# Convenience

## Composition

(.:) :: (a -> b) -> (c -> d -> a) -> c -> d -> bSource

Compose two functions, similar to `.`

from Prelude.
If `h = f .: g`

then `h x y = f (g x y)`

.