👓 Profunctor based lightweight implementation of Lenses
The prolens
package is a Haskell library with a minimal and
lightweight implementation of optics. Optic is a high-level
concept for values that provide composable access to different parts of
structures.
Prolens implements the following optics:
We created the prolens
project in pursuit of the following goals:
Profunctor
typeclass with the
QuantifiedConstraints
feature, which is not present in any other library at the moment.prolens
provides a
performant API. We use the
inspection-testing
library to guarantee that our implementation of optics compiles to
the same code as plain Haskell getters, record-update syntax and
pattern matching.prolens
library contains a
mini-tutorial on optics, enough to understand how and when to use
basic lenses and prisms.prolens
is compatible with the latest GHC compiler
versions starting from 8.6.5
.
In order to start using prolens
in your project, you
will need to set it up with the three easy steps:
Add the dependency on prolens
in your project's
.cabal
file. For this, you should modify the build-depends
section by adding the name of this library. After the adjustment,
this section could look like this:
build-depends: base ^>= 4.15
, prolens ^>= LATEST_VERSION
In the module where you wish to use composable getters and setters, you should add the import:
import Prolens (Lens', lens, view)
Now you can use the types and functions from the library:
data User = User
{ userName :: String
, userAge :: Int
}
nameL :: Lens' User String
nameL = lens userName (\u new -> u { userName = new })
main :: IO ()
main = putStrln $ view nameL (User "Johnny" 27)
If prolens
is not available on your current Stackage
resolver yet, fear not! You can still use it from Hackage by adding
the following to the extra-deps
section of your stack.yaml
file:
extra-deps:
- prolens-CURRENT_VERSION
It is the most mature Haskell library for optics. lens
provides a
richer interface, but it is heavyweight and based on Van Laarhoven (VL)
encoding of lenses.
A lightweight implementation of optics compatible with
lens
. microlens
is also minimalistic, but it doesn't provide
prisms and is based on VL encoding.
The optics
library uses the profunctor encoding. It provides much
more features than prolens
, but at the same time it's
heavyweight. Also, optics
uses an opaque representation of optics
(e.g. they are wrapped in a newtype), which means that they are
composed using the custom operator %
, while in prolens
optics
are type aliases to functions and can be easily composed with the
dot .
operator.
This library is also based on profunctor encoding (as the name suggests) and provides optics as aliases to functions. But it is more heavyweight, though it provides more features.
In addition to this per-library comparison, prolens
has a few unique
features:
inspection-testing
to guarantee the performance of
opticsoptics