generic-lens

Build Status Hackage

Generically derive isos, traversals, lenses and prisms.

This library uses GHC.Generics to derive efficient optics (traversals, lenses and prisms) for algebraic data types in a type-directed way, with a focus on good type inference and error messages when possible.

The library is described in the paper:

Csongor Kiss, Matthew Pickering, and Nicolas Wu. 2018. Generic deriving of generic traversals. Proc. ACM Program. Lang. 2, ICFP, Article 85 (July 2018), 30 pages. DOI: https://doi.org/10.1145/3236780

Package structure

generic-lens are generic-optics are designed to be drop-in replacements for each other. This means that they share the same module names. If, for whatever reason, they are both used in the same project, the module imports can be disambiguated using the -XPackageImports extension.

Getting started

A typical module using generic-lens or generic-optics will usually have the following extensions turned on:

{-# LANGUAGE AllowAmbiguousTypes       #-}
{-# LANGUAGE DataKinds                 #-}
{-# LANGUAGE DeriveGeneric             #-}
{-# LANGUAGE DuplicateRecordFields     #-}
{-# LANGUAGE FlexibleContexts          #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeApplications          #-}

In particular, NoMonomorphismRestriction can be helpful as it enables proper type inference for top-level functions without a type signature.

For usage examples, visit the documentation on hackage, or have a look in the examples and tests folders in generic-lens or generic-optics.

Performance

The runtime characteristics of the derived optics is in most cases identical at -O1, in some cases only slightly slower than the hand-written version. This is thanks to GHC’s optimiser eliminating the generic overhead.

The inspection-testing library is used to ensure (see here) that everything gets inlined away.

There is also a benchmark suite with larger, real-world examples.