[erlang-questions] How to specify a clear map type
月忧茗
yueyoum@REDACTED
Fri Sep 23 04:34:17 CEST 2016
Thanks Magnus,
I found that If I construct a map in the erl file, the dialyzer will find
an type error.
-module(xx).
-export([find_value/2]).
-type my_type() :: #{integer() := string()}.
find_value(Key, _State) when is_atom(Key) ->
State = #{1 => "abc", 2 => "def"},
find_value_1(Key, State).
-spec find_value_1(atom(), my_type()) -> string().
find_value_1(Key, State) ->
#{Key := Value} = State,
Value.
Checking whether the PLT /home/wang/.dialyzer_plt is up-to-date... yes
>
> Proceeding with analysis...
>
> xx.erl:14: Function find_value/2 has no local return
>
> xx.erl:19: Function find_value_1/2 has no local return
>
> xx.erl:20: The pattern #{Key:=Value} can never match the type #{1:=[97 |
>> 98 | 99,...], 2:=[100 | 101 | 102,...]}
>
> done in 0m1.42s
>
> done (warnings were emitted)
>
>
>
But , if the map is not constructed in this erl file, dialyzer can not
find any error.
-module(xx).
-export([find_value/2]).
-type my_type() :: #{integer() := string()}.
-spec find_value(atom(), my_type()) -> string().
find_value(Key, State) when is_atom(Key) ->
find_value_1(Key, State).
-spec find_value_1(atom(), my_type()) -> string().
find_value_1(Key, State) ->
#{Key := Value} = State,
Value.
Checking whether the PLT /home/wang/.dialyzer_plt is up-to-date... yes
>
> Proceeding with analysis... done in 0m1.35s
>
> done (passed successfully)
>
>
>
2016-09-23 7:01 GMT+08:00 Magnus Lång <margnus1@REDACTED>:
> On 2016-09-22 18:39, 月忧茗 wrote:
>
> According this document: http://erlang.org/doc/reference_manual/typespec.
> html
>
> I can define a map type like this:
>
> -type my_type() :: #{integer() := string()}.
>
>
> I have a map called State, it's type is `my_type`, key type is integer,
> value type is string.
>
> -spec find_value(atom(), my_type()) -> string().
>> find_value(Key, State) when is_atom(Key) ->
>> #{Key := Value} = State,
>> Value.
>
>
>
> Using dialyzer analysis the file. nothing happens.
> dialyzer say there is no error for this file.
>
> I know maps are dynamic, my_type() just meas this map must have a integer
> key associated with a string value.
> But not limit to add other type key and value in the map.
>
> My question is that Is it possible limit the map types of key and value ?
> So dialyzer can find the match error in my program.
>
>
> Actually, your type is already restricted in this way, and I'm surprised
> your find_value example does not produce any warnings. Dialyzer should be
> quite capable of finding the problem. Indeed, if we enforce the type of the
> State argument in this (slightly ridiculous) way instead of using a type
> specification, the problem *is* found:
>
> find_value(Key, State) ->
> StateList = [{K, V} || {K, V} <- maps:to_list(State),
> is_integer(K), is_list(V)],
> find_value_1(Key, maps:from_list(StateList)).
>
> find_value_1(Key, State) when is_atom(Key) ->
> #{Key := Value} = State,
> Value.
>
> When I get some time over, I'll have a look at why your example does not
> fail, but for now rest assured that your type syntax is correct and means
> what you want it to mean.
>
> // Magnus
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
--
My GitHub
https://github.com/yueyoum
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160923/eb608219/attachment.htm>
More information about the erlang-questions
mailing list