Elm-accessors, a library to describe an use data relations


#1

I just released elm-accessors 2.0.0.

An example drawn from the readme:

recordFoo =
  makeOneToOne
    .foo
    (\change record -> {record | foo = change record.foo})

recordBar =
  makeOneToOne
    .bar
    (\change record -> {record | bar = change record.bar})

onEach = makeOneToN List.map List.map

myData = {foo = [ {bar = 3}
                , {bar = 2}
                , {bar = 0}
                ]
         }

myAccessor = recordFoo << onEach << recordBar

getter   = get  myAccessor myData
-- returns [3, 2, 0]
setter   = set  myAccessor 2 myData
-- returns {foo = [{bar = 2}, {bar = 2}, {bar = 2}] }
transorm = over myAccessor (\n -> n*2) myData
-- returns {foo = [{bar = 6}, {bar = 4}, {bar = 0}] }

The goal is to explore new ways to describe relations between data (especially how to nest a program inside another program), as well as to provide a partial replacement for arturopala/elm-monocle or evancz/focus. The lens implementation is heavily inspired from Haskell’s lenses.

I would be very glad to hear comments about the documentation: any feedback on how to improve it is welcome.


#2

Interesting!
Could you explain how elm-accessors’ approach to lenses differs from elm-monocle and elm-focus?


#3

elm-monocle and focus are both using as core brick a record containing methods to get and modify content (respectively, Lens/Iso/Prism/Optional and Focus). They then use custom operators to compose them.

elm-accessors is different in two ways:

  • First, since elm-accessors was written with 0.19 in mind, I don’t have the privilege of using custom operators. Therefore, I fall back to generic composition. This means my core brick must be of type a -> b in order to fit in <<'s type (b -> c) -> (a -> b) -> a -> c.
    *Second, since I can’t use a different operator for the different types of constructs elm-monocle offers, I have to unify monocle's Lens/Iso/Prism/Optional into a single concept.

In the library, the essential reason why we distinguish accessors and Relation is that a relation is the equivalent brick to the other libraries, while accessors wrap relations into a -> b functions. As users won’t use relations besides seeing them in type signature, the basic block of the lib is accessors.

Fortunately, the theory for these changes has already been laid down by haskell’s lens. The only problems I had to solve was that this library uses several things we don’t have in Elm (mainly rank-n-types and functors).

A last note regarding elm-monocle, it does more than what elm-accessors does. I decided to restrict my work to accessing nested data, and therefore, there is no support for Iso and Prism, only for Lens and optional. There is no barrier to add support for them, but I feel like this would add understanding complexity for use cases that are not related to my field of interest.


#4

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.