optic

#

Copyright (c) 2019 John Krukoff

Version: 0.1.0

Authors: John Krukoff (github@cultist.org).

Overview

Camera Lenses

This is an Erlang/OTP library for retrieving and modifying nested values, in the spirit of Haskell's lens library. Functional selectors for deeply nested values are constructed by composing "optics", each of which specifies a way to focus on a particular kind of value.

For example, say we had a list of deserialized JSON entities representing pets for sale that we wanted to modify.


> Pets = [#{
    <<"id">> => 628178654,
    <<"name">> => <<"spot">>,
    <<"status">> => <<"available">>,
    <<"category">> => #{
      <<"id">> => 3216199393,
      <<"name">> => <<"dog">>
    }}].

We could then update all pets to a new status by:


> optic:put([optic_lists:all(), optic_maps:key(<<"status">>)],
            Pets,
            <<"sold">>).
{ok,[#{
  <<"id">> => 628178654,
  <<"name">> => <<"spot">>,
  <<"status">> => <<"sold">>,
  <<"category">> => #{
    <<"id">> => 3216199393,
    <<"name">> => <<"dog">>
  }}]}

Getting Started

This library is published to hex.pm as optic. If you're using rebar3 as your build tool, it can be added as a dependency to your rebar.config as follows:


{deps, [{optic}]}.

Usage

Optics

Examples

Contributing

Please fork the repo and submit a PR. Tests are run via:


rebar3 eunit

Documentation is autogenerated using edown and edoc via:


rebar3 as markdown edoc

The application has only been tested with Erlang/OTP 21 on Windows 10. Reports of success (or failure!) on other versions and operating systems are appreciated.

Lineage

I first encountered lenses via theDatum library, but wanted a version that supported traversables instead of lenses in order to support updating multiple elements. As lenses are a special case of traversables, this allowed for using a single type to represent both.

There are a number of good introductions to lenses, this was the most accessible for me.

This library was initially conceived with the intention of making it easy to modify deeply nested JSON, so JSON related data structures were the first implemented.

Attribution

Image by Bill Ebbesen CC BY-SA 3.0 https://creativecommons.org/licenses/by/3.0/deed.en

Modules

optic
optic_generic
optic_lists
optic_maps
optic_proplists
optic_tuples