Updating nested records, again

Hello,

I suggest you pay attention to Richard and other people here saying that simplifying your data may just solve your problem.

…That being said, if you’ve already done that exercise and are really in need for some higher level of abstraction to manipulate nested data blobs, I think lenses are a good way to reduce the burden of accessing and updating data. Someone else has told you about elm-monocle, so I will introduce my own, brand new library:

http://package.elm-lang.org/packages/bChiquet/elm-accessors/latest

In your data example, updating the record would be written as:

newModel = set (foo << bar << baz) "hello again" model

Then you need to define foo, bar and baz, but they all look similar:

foo : Accessor a b c -> Accessor {rec | foo : a} b c
foo (Accessor sub) =
      Accessor { get  = \super -> sub.get super.foo
                      , over = \f -> \super -> { super | foo = sub.over f super.foo }
                      }

by the way, I like to put them in a record in order to avoid polluting the toplevel namespace:

r = {
    bar = \(Accessor sub) ->
      Accessor { get  = \super -> sub.get super.bar
               , over = \f -> \super -> { super | bar = sub.over f super.bar }
               }
    ,
    foo = \(Accessor sub) ->
      Accessor { get  = \super -> sub.get super.foo
               , over = \f -> \super -> { super | foo = sub.over f super.foo }
               }
    }

The benefits of this library, compared to monocle or focus, is that it doesn’t need you to introduce new operators : foo, bar and baz can be composed with the natural << and >> composition operators. I expect this to survive the 0.19 changes better.

(The documentation was just finished yesterday, so feel free to ask questions or comment on it, I will gladly take all the feedback).