Giter Club home page Giter Club logo

prolens's Introduction

prolens

Prolens Logo

GitHub CI Hackage MPL-2.0 license

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:

  • Lens โ€” composable getters and setters
  • Prism โ€” composable constructors and deconstructors
  • Traversal โ€” composable data structures visitors

Goals

We created the prolens project in pursuit of the following goals:

  1. Education. Teach others how to implement and work with profunctor optics. This also means that some underlying types or type variables have different unconventional names
  2. Learning. Explore new concepts ourselves and understand better abstractions used in the implementation.
  3. Minimalism. Keep the number of dependencies, features and code low, but still solve common problems.
  4. Performance. Despite being minimalist, implement optics so they are as fast as manual and clumsy pattern matching.
  5. Exploration. Understand how different modern Haskell features can work on improving interface and bring new flavour into standard approaches. Because of this, we implement our own Profunctor typeclass with the QuantifiedConstraints feature, which is not present in any other library at the moment.
  6. Profunctors. We use profunctor encoding of optics because it has more elegant design with fewer surprises.

Features

  1. Lightweight. Only base in dependencies. The project itself also has a rather small amount of code.
  2. Fast. Despite being lightweight, 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.
  3. Excellent documentation. The prolens library contains a mini-tutorial on optics, enough to understand how and when to use basic lenses and prisms.
  4. Beginner-friendly. The abstractions in the implementation are hardcore, but our documentation presents the concept in a beginner-friendly and approachable manner.
  5. Lawful. We use property-based testing to make sure that laws of all underlying abstractions are verified.

How to use

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:

  1. 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
  2. In the module where you wish to use composable getters and setters, you should add the import:

    import Prolens (Lens', lens, view)
  3. 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)

Usage with Stack

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

Comparison to other libraries

  1. lens

    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.

  2. microlens

    A lightweight implementation of optics compatible with lens. microlens is also minimalistic, but it doesn't provide prisms and is based on VL encoding.

  3. optics

    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.

  4. profunctor-optics

    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:

  • Beginner-friendly documentation with usage examples
  • Usage of inspection-testing to guarantee the performance of optics
  • Property-based tests of lens and typeclasses laws to make sure that all abstractions behave properly

Acknowledgement

  • Edward Kmett for lenses and profunctor typeclasses
  • Well-Typed for the implementation of optics

prolens's People

Contributors

chshersh avatar cristhianmotoche avatar vrom911 avatar xplosunn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

prolens's Issues

Refactor laws tests

Implement general functions for laws property-testing to avoid code duplication. Ideally, the calls to laws should look like this:

lawsSpecs :: Spec
lawsSpecs = describe "Laws" $ do
    describe "Profunctor" $ do
        profunctorLaws "->"     genFunction (===)
        profunctorLaws "Fun"    genFun      eqFun
        profunctorLaws "Forget" genForget   eqForget

Clarify what is meant by 'lightweight'

As u/arybczak mentions on r/haskell, it's not entirely clear what the README is supposed to mean when it says that prolens is a "lightweight" optics library in comparison to optics.

I'm assuming that this is supposed to be "conceptually lightweight", since prolens seems to be billed as an educational library, but I figured it would be worth opening an issue to clarify.

Thanks!

Kleisli instead of Fun

It doesn't seem obvious to me why Fun is distinct from Kleisli (if it is not distinct, then why reimplement it?):

prolens/src/Prolens.hs

Lines 62 to 65 in 559e106

-- | @since 0.0.0.0
newtype Fun m a b = Fun
{ unFun :: a -> m b
}

Screenshot 2020-10-11 at 13 21 33

The Functor instance also seems to be identical.

Add typeclasses law tests

  • Profunctor: (->)
  • Profunctor: Fun
  • Profunctor: Forget
  • Strong: (->)
  • Strong: Fun
  • Strong: Forget
  • Choice: (->)
  • Choice: Fun
  • Choice: Forget
  • Monoidal: (->)
  • Monoidal: Fun
  • Monoidal: Forget

Add custom type-errors

Whenever possible. Maybe also use type-errors-pretty is we will have a lot of type errors ๐Ÿค”

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.