Warning - it is still in experimental stage.
primal is a ground up design of a new interface for mutable and effectful operations
that uses industry best practices as well as novel approaches to improve usability and
performance.
Status
| Language | Travis | Azure | Coveralls |
|---|---|---|---|
| Package | Hackage | Nightly | LTS |
|---|---|---|---|
primal |
|||
primal-memory |
|||
primal-test |
What is it all about?
"Haskell is the world’s finest imperative programming language." - SPJ
It is hard to argue with this statement. However, despite that Haskell makes effectful code much safer, it has never been very friendly when it actually came to writing imperative programs. It seems like that most of the design time is spent on three distinct spectrums:
- At the very top is the purely functional code. These are your
Nums,Foldables,Applicatives etc. In other words the warm and fuzzy world of immutability, idempotency and refertial transperency. - At the very bottom is the code that interfaces with real world. All of the
IOstuff that you can think of: file system, networks, databases, concurrency etc. - And the stuff in the middle. All the various effect systems that try to somehow marry
the above two paradigms into one cohesive and usable abstraction. These are your
tranformers,mtls,polysemys,fused-effectsetc.
Incidentally, there is a whole spectrum that is usually overlooked and neglected. Mutable
data structures. Mutable operations on them run in ST monad or possibly in IO,
but often with safe escape hatches to the warm and fuzzy world of immutability. This
spectrum can even sometimes encapsulate parallelization, which can also yield
determinsitic and pure results, when implemented properly.
This project attempts to augment Haskell's imperative capabilities by filling this mutable spectrum, while providing interoperability with the rest of the Haskell ecosystem.
Prior art
The notable and predominantly used packages in this area of mutability that we are trying to improve are:
primitive/vectorand derivativesbasement/memoryproject.
There are a few other packages that touch up on this space, but none of them succeed in providing a solution.
Without attacking the root of the problem we cannot make the situation better. For that
reason we also will look at some of the techniques, which were borrwoed from other
packages: unliftio, unlift, exceptions.
New approach
There are a few crucial and novel approaches this package employs:
- All mutable types have their state token type argument ordered at the end:
MArray a svsMArray s a - Unboxing of complex types