fraxl alternatives and similar packages
Based on the "Concurrency" category.
Alternatively, view fraxl alternatives based on common mentions on social networks and blogs.
-
haxl
A Haskell library that simplifies access to remote data, such as databases or web-based services. -
chaselev-deque
A collection of different packages for CAS based data structures. -
unagi-chan
A haskell library implementing fast and scalable concurrent queues for x86, with a Chan-like API -
lifted-async
Run lifted IO operations asynchronously and wait for their results -
libcspm
The library FDR3 uses for parsing, type checking and evaluating machine CSP. -
cspmchecker
The library FDR3 uses for parsing, type checking and evaluating machine CSP. -
threads-supervisor
Simple, IO-based Haskell library for Erlang-inspired thread supervisors -
concurrent-machines
Concurrency features for the Haskell machines package -
concurrent-supply
A fast globally unique variable supply with a pure API -
slave-thread
A principal solution to ghost threads and silent exceptions -
sirkel
Sirkel; a Chord DHT in haskell. Node failure, replication and batteries included! -
thread-supervisor
A simplified implementation of Erlang/OTP like supervisor for GHC thread -
unagi-bloomfilter
A fast, cache-efficient, concurrent bloom filter in Haskell -
token-bucket
Haskell rate limiter library using lazy token bucket algorithm -
timers
Simple package that implements timers. Both "one-shot" and "repeating" timers are implemented. -
split-channel
Control.Concurrent.Chan split into sending and receiving halves.
Updating dependencies is time-consuming.
Do you think we are missing an alternative of fraxl or a related project?
Popular Comparisons
README
Fraxl
Fraxl is a library based on Facebook's Haxl. The goal is to decompose Haxl into more general parts, in order to form a stronger composition with better type safety and purity.
Usage
Using Fraxl is fairly similar to Haxl.
You define a request data type (often a GADT), and a Fetch
function.
With this, Fraxl is able to perform requests concurrently.
data MySource a where
MyString :: MySource String
MyInt :: MySource Int
type Fetch f m a = ASeq f a -> m (ASeq m a)
fetchMySource :: MonadIO m => Fetch MySource m a
fetchMySource ANil = return ANil
fetchMySource (ACons f fs) = (ACons. liftIO . wait)
<$> liftIO (async $ downloadSource f)
<*> fetchMySource fs
> let a = ...
> runFraxl fetchMySource a
You'll notice a few things here.
For one, a data source can choose what monad it lives in.
Unlike Haxl, which only lets you live in IO
,
Fraxl is a monad transformer, allowing you to use arbitrary underlying monads.
Thus, maintaining state between fetches can be left up to the data source.
This can be used for several things, such as caching or session management.
Unlike Haxl, a data source isn't tied to one fetch function.
Haxl requires your data source to implement the DataSource
class.
By passing a Fetch
function to Fraxl,
it's easy to have multiple interpretations of the same data source.
This is useful for mocking and testing data sources.
ASeq :: (* -> *) -> * -> *
is similar to a heterogenous list.
It is the data structure used by the fast free applicative.
Interpreting this is akin to interpreting the free applicative.
The Fetch
function takes a list of f
requests,
and for each request, returns an m
action that waits on the response.
That is, fetch
should start background threads for requests,
and return all the actions for Fraxl to block with until they complete.
This way, Fraxl can have many requests start their work in parallel,
and call all their wait-actions together.
Composition
Fraxl is a composition of general tools.
At the base of this composition is a free monad transformer
(the basis of which is described here).
This is because Fraxl (and Haxl) is necessarily a free monad.
It's taking arbitrary data sources of kind * -> *
,
and constructing a monad out of them.
Since there exists a free monad transformer with applicative optimization,
there's no reason not to use it and get the transformer structure for free.
The next layer of the composition is the free applicative.
The free monad with applicative optimization uses any applicative
(rather than any functor, as with the traditional free monad).
Since the free applicative uses any type of kind * -> *
,
it is the perfect candidate for this layer.
It allows Fraxl to see all the requests made in
an applicative computation at once, which is how Fraxl can parallelize them.
The final layer is the data source layer.
It is user-specified, but will often be a Union :: [* -> *] -> * -> *
.
The union is essentially a nested either type
over any number of type constructors.
Union '[f, g, h] a ≡ Either (f a) (Either (g a) (h a))
If all of those types are data sources, the union allows Fraxl to handle all of them as one data source, in one layer of Fraxl. The nice thing about this is that it makes it type safe to use a data source. Whereas Haxl will simply trust that you know what you're doing, Fraxl will make it a type error to forget to initialize a data source, or call a computation without guaranteeing its data source is available.
The data source layer can be easily modified.
Caching is a substitution of this layer that replaces the data
source with one that caches the results of the original.
It does this with a dependent map, whose keys are requests,
and whose values are MVars
of the results.
If an uncached request is requested,
an empty MVar
is inserted into the cache map, the original fetch
is called,
and the result is stored in the MVar
.
If a cached request is requested,
the wait-action returned will simply be readMVar
.
Check out [the example](examples/src/Main.hs) for a demonstration.