request-monad alternatives and similar packages
Based on the "Control" category.
Alternatively, view request-monad alternatives based on common mentions on social networks and blogs.
-
fused-effects
A fast, flexible, fused effect system for Haskell -
transient
A full stack, reactive architecture for general purpose programming. Algebraic and monadically composable primitives for concurrency, parallelism, event handling, transactions, multithreading, Web, and distributed computing with complete de-inversion of control (No callbacks, no blocking, pure state) -
recursion-schemes
Generalized bananas, lenses and barbed wire -
apecs
a fast, extensible, type driven Haskell ECS framework for games -
distributed-closure
Serializable closures for distributed programming. -
extensible-effects
Extensible Effects: An Alternative to Monad Transformers -
classy-prelude
Type classes for mapping, folding, and traversing monomorphic containers -
auto
Haskell DSL and platform providing denotational, compositional api for discrete-step, locally stateful, interactive programs, games & automations. http://hackage.haskell.org/package/auto -
selective
Selective Applicative Functors: Declare Your Effects Statically, Select Which to Execute Dynamically -
classy-prelude-yesod
Type classes for mapping, folding, and traversing monomorphic containers -
safe-exceptions
Safe, consistent, and easy exception handling -
abstract-par
Type classes generalizing the functionality of the 'monad-par' library. -
these
An either-or-both data type, with corresponding hybrid error/writer monad transformer. -
hask
Category theory for Haskell with a lens flavor (you need GHC 7.8.3, not 7.8.2 to build this!) -
ComonadSheet
A library for expressing "spreadsheet-like" computations with absolute and relative references, using fixed-points of n-dimensional comonads. -
transient-universe
A Cloud monad based on transient for the creation of Web and reactive distributed applications that are fully composable, where Web browsers are first class nodes in the cloud -
cloud-haskell
This is an umbrella development repository for Cloud Haskell -
distributed-process-platform
DEPRECATED (Cloud Haskell Platform) in favor of distributed-process-extras, distributed-process-async, distributed-process-client-server, distributed-process-registry, distributed-process-supervisor, distributed-process-task and distributed-process-execution -
distributed-fork
A distributed data processing framework in Haskell. -
monad-validate
(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexi-lambda/monad-validate) A Haskell monad transformer library for data validation -
monad-control
Lift control operations, like exception catching, through monad transformers -
ixmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling fine-grained reasoning about effects. -
effect-monad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling fine-grained reasoning about effects. -
freer-effects
An implementation of "Freer Monads, More Extensible Effects". -
operational
Implement monads by specifying instructions and their desired operational semantics. -
monad-time
Type class for monads which carry the notion of the current time.
Clean code begins in your IDE with SonarLint
Do you think we are missing an alternative of request-monad or a related project?
README
request-monad
This library exports a monad that can be used to abstract a request sending/response handling pattern. It can be used to implement type-transforming middleware, as well as a way to easily implement stubbing.
Installation
From the command line:
$ cabal install request-monad
To use data types and functions export from this library:
import Control.Monad.Request
Usage
Using RequestT r r' m a
abstracts sending requests of type r
, and handling responses of r'
.
Below is an example of using RequestT
to ask for somebody's name and age.
Note that there is no logic about how to get and return the strings in getNameAndAge
, that's all handled in prompt
.
import Control.Monad
import Control.Monad.Request
import System.IO
getNameAndAge :: Monad m => RequestT String String m (String, Int)
getNameAndAge = do
name <- send "Name: "
age <- liftM read $ send "Age: "
return (name, age)
prompt :: String -> IO String
prompt str = putStr str >> hFlush stdout >> getLine
main :: IO ()
main = do
(name, age) <- runRequestT getNameAndAge prompt
putStrLn $ name ++ " is " ++ show age ++ " years old."
Below is an example of an echo server, which just returns the exact input that it was given.
import Control.Monad.Request
pingPong :: Monad m => RequestT String String m (String, String)
pingPong = do
a <- send "ping"
b <- send "pong"
return (a, b)
main :: IO ()
main = do
let (a, b) = runRequest pingPong id
putStrLn $ "a: " ++ a -- Prints "a: ping"
putStrLn $ "b: " ++ b -- Prints "b: pong"
Aside from implementation-independant requests, this abstraction also simplifies adding request/response middleware. The code below adds JSON deserialization to each response.
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad
import Control.Monad.Request
import qualified Data.Aeson as A
import qualified Data.ByteString.Lazy as B
deserialize :: (A.FromJSON a, Monad m) => B.ByteString -> m (Maybe a)
deserialize = return . A.decode
tryTwice :: Monad m => RequestT B.ByteString B.ByteString m (Maybe A.Value)
tryTwice = mapResponseT deserialize $ do
a <- send "request one"
b <- send "request two"
return $ a `mplus` b
handleRequest :: Monad m => B.ByteString -> B.ByteString
handleRequest "request one" = return "not json"
handleRequest x = "[15]"
main :: IO ()
main = do
let res = runRequest tryTwice handleRequest
print $ res -- Prints "Just (Array (fromList [Number 15.0]))"
TODO
- Add a strict version of
RequestT