[erlang-questions] maps: pattern-match absent key?

Fred Hebert mononcqc@REDACTED
Wed Feb 19 16:57:38 CET 2014


It sounds to me like it would be much nicer to do something like this:

1> Default = #{abc => 123, def => 456, ghi => 789}.
#{abc => 123,def => 456,ghi => 789}
2> maps:merge(Default, #{}).
#{abc => 123,def => 456,ghi => 789}
3> maps:merge(Default, #{abc => <<"bin">>}).
#{abc => <<"bin">>,def => 456,ghi => 789}
4> maps:merge(Default, #{abc => <<"bin">>, def => hello}).
#{abc => <<"bin">>,def => hello,ghi => 789}

According to the spec in EEP-43:

    maps:merge(M0 :: map(), M1 :: map()) -> M2 :: map().

    Syntax equivalence: none

    Merges two maps into a single map. If two equal keys exists in both
    maps the value in map M0 will be superseded by the value in map M1.

My recommendation is to not have to add a guard, and instead just use a
map with all the default values and merge them in with yours. The
default map has to be the first argument so that its values can be
superseeded by the submitted maps.

This is going to be both shorter, simpler, and likely more readable,
without needing to call your "check my default value" function over
every element up until it reaches a fixed point.

Regards,
Fred.

On 02/19, Daniel Goertzen wrote:
> Is there any possibility of getting maps:is_key() as a guard so missing
> keys can be detected more directly?
> 
> Consider this case of filling defaults into a map before the final clause
> processes it:
> 
> 
> myfun(M) when not is_key(abc, M) ->
>   myfun(M#{abc=>123});
> 
> myfun(M) when not is_key(def, M) ->
>   myfun(M#{def=>456});
> 
> myfun(M) when not is_key(pqr, M) ->
>   myfun(M#{abc=>789});
> 
> myfun(#{abc:=ABC, def:=DEF, pqr:=PQR}) ->
>   do_stuff.
> 
> 
> I can't see how fail clauses could scale up to something like this.  Now
> there are certainly other ways of solving the above problem (lists:foldl
> comes to mind), but I still think having is_key() as a guard would be
> valuable in certain situations.  It feels about as useful as...
> 
> f(X) when X/=123 ->  do_stuff.
> 
> ... which I don't do often, but it is good to know it is there when I need
> it.
> 
> 
> Dan.
> PS.  I accidentally posted the original question to erlang-patches, moving
> to erlang-questions.
> 
> 
> On Tue, Feb 18, 2014 at 2:23 PM, Björn-Egil Dahlberg <
> wallentin.dahlberg@REDACTED> wrote:
> 
> > Yes, with fail clauses.
> >
> > f(#{ a := _ }) -> {a,present};
> > f(_) -> {a,absent}.
> >
> >
> >
> > 2014-02-18 20:55 GMT+01:00 Daniel Goertzen <daniel.goertzen@REDACTED>:
> >
> >> Is there a way to pattern-match the absence of a key in a map?
> >>
> >> Dan.
> >>
> >> _______________________________________________
> >> erlang-patches mailing list
> >> erlang-patches@REDACTED
> >> http://erlang.org/mailman/listinfo/erlang-patches
> >>
> >>
> >

> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list