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.
-
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) -
fused-effects
A fast, flexible, fused effect system for Haskell -
recursion-schemes
Generalized bananas, lenses and barbed wire -
apecs
a fast, extensible, type driven Haskell ECS framework for games -
classy-prelude
Type classes for mapping, folding, and traversing monomorphic containers -
classy-prelude-yesod
Type classes for mapping, folding, and traversing monomorphic containers -
distributed-closure
Serializable closures for distributed programming. -
safe-exceptions
Safe, consistent, and easy exception handling -
these
An either-or-both data type, with corresponding hybrid error/writer monad transformer. -
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 -
extensible-effects
Extensible Effects: An Alternative to Monad Transformers -
ComonadSheet
A library for expressing "spreadsheet-like" computations with absolute and relative references, using fixed-points of n-dimensional comonads. -
abstract-par
Type classes generalizing the functionality of the 'monad-par' library. -
hask
Category theory for Haskell with a lens flavor (you need GHC 7.8.3, not 7.8.2 to build this!) -
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-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 -
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 -
monad-control
Lift control operations, like exception catching, through monad transformers -
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". -
ixmonad
Provides 'graded monads' and 'parameterised monads' to Haskell, enabling fine-grained reasoning about effects. -
operational
Implement monads by specifying instructions and their desired operational semantics. -
lens-tutorial
The missing tutorial module for the lens library -
monad-time
Type class for monads which carry the notion of the current time.
InfluxDB - Power Real-Time Data Analytics at Scale
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