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

Magnus Lång <>
Fri Sep 23 01:01:01 CEST 2016


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160923/9f992d58/attachment.html>


More information about the erlang-questions mailing list