Reputation: 647
How do you specify arguments and return types type for functions within functions using the Erlang Dialyzer, such as functions from libraries or Behavior
(e.g gen_server
s gen_server:reply/2
). For instance in the MVR code provided below, how can I specify that the maps:put/3
gets the right order of arguments, such that it's thrird argument is a map()
?
Furthermore is there a way to ensure it for variables within a function and/or globally, such that for instance an integer I declare within a function gets integer()
?
-module(example_module).
-export([my_function/1, state_changer/3, test_function/0]).
-type map_arg() :: #{key1 => integer(), key2 => atom()}.
-type move() :: rock | paper | scissor.
-type playersmap() :: #{players => {pid(), pid()}} | #{players => {pid(), pid()}, fst_mover => {{pid(),_}, move()}}.
-spec my_function(Map_arg :: map_arg()) -> ok.
my_function(Map) ->
ok.
test_function() ->
CorrectMap = #{key1 => 1, key2 => 'value'},
IncorrectMap = #{key1 => 1, key2 => 2},
my_function(CorrectMap),
my_function(IncorrectMap),
state_changer({move, rock}, {self(), tag}, #{players => {self(), self()}, fst_mover => {{self(), tag}, scissor}}).
-spec state_changer({move, Choice :: move()}, From :: {pid(), _}, PlayersMap :: playersmap()) -> {reply, playersmap()}.
state_changer({move, Choice}, From, PlayersMap) ->
{CurId, _} = From,
{P1Id, P2Id} = maps:get(players, PlayersMap),
case CurId of
P1Id ->
PlayersMapNew = maps:put(fst_mover, {From, Choice}, PlayersMap),
{reply, PlayersMapNew};
P2Id ->
PlayersMapNew = maps:put(fst_mover, {From, Choice}, PlayersMap),
{reply, PlayersMapNew}
end.
EDIT
So far the only thing I have been able to come up with is some sort of wrapper around the functions that I would like to declare some type specificity for. Such as -spec my_maps_put(From :: reference(), Choice :: move(), PlayersMap :: playersmap())-> PlayersMapNew :: playersmap()
, but I don't know if this is the best way.
Upvotes: 1
Views: 80