[erlang-questions] adding maps:merge_nested/2

Vans S <>
Tue Nov 15 20:55:17 CET 2016


What would happen if we had:

Map1 = #{  a => #{ b => 2, f=> #{}}  },
Map2 = #{ a=> #{b => 3, c => 4, d=> #{e=> 5}} }

Would we need to do our own calls to recurse into each nest?

On Tuesday, November 15, 2016 2:34 PM, Jesper Louis Andersen <> wrote:



Hi Vans,

Suppose we have

Map1 = #{ a => 1, b => 2 },
Map2 = #{ b => 3, c => 3 },

and we call maps:merge(F, Map1, Map2). F will be called 3 times with the following inputs:

F(a, {left, 1}) %% because a is only in the left side of the map.
F(b, {both, 2, 3}) %% since b is in both maps and the value 2 is in the left and 3 in the right
F(c, {right, 3}) %% since c is only in the right map

In each case, we can return a new value {ok, V} for some new value V, perhaps computed from the input. Or we can return undefined in the case we wish to have the new map ignore that key completely and omit it from the produced/merged map.


On Tue, Nov 15, 2016 at 4:23 PM Vans S <> wrote:

> fun
>>  (K, {left, VL}) -> Res;
>>  (K, {right, VR}) -> Res;
>>  (K, {both, VL, VR}) -> Res
>> end
>
>Some questions on what VL/VR are once inside a nest, or does that happen all behind the scenes (going in nests). So you only need to compare the current values and return what will replace them?
>
>It seems like this is a more common use case then I initially thought. Having a general way to do this in erlang/OTP would be useful.
>
>
>
>
>On Tuesday, November 15, 2016 7:54 AM, Jesper Louis Andersen <> wrote:
>
>
>
>
>
>
>On Mon, Nov 14, 2016 at 9:20 PM Michael Truog <> wrote:
>
>
>>The main merge function you are missing in the maps module, is the merge/3 (instead of merge/2) that is common in other modules (like the dict/orddict modules).  I added an implementation of merge/3 at https://github.com/okeuday/mapsd due to needing the dict API elsewhere.  With the merge/3 function it should be easier to merge nested maps, in whatever way is required, since one size shouldn't fit all.
>>
>
>In OCaml, you often have a merge-function like this one:
>
>
>val merge : ('k, 'v1, 'cmp) t -> ('k, 'v2, 'cmp) t -> f:(key:'k -> [
>| `Left of 'v1
>| `Right of 'v2
>| `Both of 'v1 * 'v2
>] -> 'v3 option) -> ('k, 'v3, 'cmp) t
>
>
>which means that you have to supply a function of the form
>
>
>fun
>
>  (K, {left, VL}) -> Res;
>
>  (K, {right, VR}) -> Res;
>
>  (K, {both, VL, VR}) -> Res
>
>end
>
>
>where Res is either undefined | {ok, Result} for some result value. The semantics are that left,right, and both encodes on which side the value was in the input maps. And the Res encodes if a new value should be produced in the new map.
>
>_______________________________________________
>>erlang-questions mailing list
>>
>>http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>


More information about the erlang-questions mailing list