[erlang-questions] How to specify a clear map type

月忧茗 <>
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 <>:

> 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
> 
> 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.html>


More information about the erlang-questions mailing list