Overloaded function specifications as types

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Overloaded function specifications as types

Dániel Szoboszlay
A function's type specification can be overloaded:

-spec foo(integer()) -> integer()
       ; (atom()) -> atom().

Is there a way I can use this overloaded function's type in non-spec contexts? Like I want to say bar/1 takes a function as an argument that has a spec like foo/1 above.

I can think of the following options, but neither of them is exactly what I want:

-spec bar(fun((integer() | atom()) -> integer() | atom())) -> ok.
%% Allows a function taking an integer and returning an atom.

-spec bar(fun((integer()) -> integer()) | fun((atom()) -> atom())) -> ok.
%% Allows fun erlang:atom_to_list/1, which doesn't work on integers at all.

Any better ideas? I'm sure Dialyzer can somehow represent internally the overloaded function types, but is there a way I can write them myself?

Tanks,
Daniel

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Overloaded function specifications as types

Alex S.

23 янв. 2017 г., в 13:30, Dániel Szoboszlay <[hidden email]> написал(а):

A function's type specification can be overloaded:

-spec foo(integer()) -> integer()
       ; (atom()) -> atom().

Is there a way I can use this overloaded function's type in non-spec contexts? Like I want to say bar/1 takes a function as an argument that has a spec like foo/1 above.

I can think of the following options, but neither of them is exactly what I want:

-spec bar(fun((integer() | atom()) -> integer() | atom())) -> ok.
%% Allows a function taking an integer and returning an atom.

-spec bar(fun((integer()) -> integer()) | fun((atom()) -> atom())) -> ok.
%% Allows fun erlang:atom_to_list/1, which doesn't work on integers at all.
Unfortunately, that requires having contravariant first-class types, which Dialyzer doesn’t support by design currently.
Best thing you can do in your case is writing fun((X) -> X) when X :: atom().

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Overloaded function specifications as types

Kostis Sagonas-2
In reply to this post by Dániel Szoboszlay
On 01/23/2017 11:30 AM, Dániel Szoboszlay wrote:

> Is there a way I can use this overloaded function's type in non-spec
> contexts? Like I want to say bar/1 takes a function as an argument that
> has a spec like foo/1 above.
>
> I can think of the following options, but neither of them is exactly
> what I want:
>
>... <SKIP>
>
> -spec bar(fun((integer()) -> integer()) | fun((atom()) -> atom())) -> ok.
> %% Allows fun erlang:atom_to_list/1, which doesn't work on integers at all.

I'm seriously confused as I do not see anything related to lists here...

Can you elaborate?

Kostis
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Overloaded function specifications as types

Dániel Szoboszlay
> -spec bar(fun((integer()) -> integer()) | fun((atom()) -> atom())) -> ok.
> %% Allows fun erlang:atom_to_list/1, which doesn't work on integers at all.

I'm seriously confused as I do not see anything related to lists here...

Can you elaborate?


I'm sorry, editing mistake! atom_to_list is of course not a good example. (I started off with different code samples and edited them a couple of times.)

The correct example would be a function that only takes atoms and returns atoms. E.g.

good_example(ok) -> ok;
good_example(Other) when is_atom(Other) -> error.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions