[erlang-questions] Dialyzer question

Steve Strong steve@REDACTED
Mon Nov 14 11:40:29 CET 2011


Hi All,  

I have a question on the behaviour of Dialyzer with higher-order functions.  Consider the following trivial code:

-module(test).

-compile(export_all).

-record(rec1, {fred}).
-record(rec2, {harry}).

test() ->
    #rec2{} = do_something(1, fun map/1).

do_something(Num, MapFun) ->
    MapFun(Num).

map(_X) ->
    #rec1{}.

If I run Dialyzer against it, I get no errors or warnings logged, even though it's quite apparent that it will fail.  I would have expected that Dialyzer could infer that the return type of do_something was the return type of MapFun;  within the context of do_something(), that is clearly any(), but within the context of test() I would have thought that it could see that do_something() is actually going to return a #rec1{} record, that being the return type of map().

If I replace the call to MapFun with a call to map(), as in:

do_something(Num, _MapFun) ->
    map(Num).


Then everything works as expected - Dialyzer correctly tells me that my code is broken.  Is there anything I can do to "teach" dialyzer how to interpret the MapFun?  It works as I would like with functions such as lists:map():

-module(test).

-compile(export_all).

-record(rec1, {fred}).
-record(rec2, {harry}).

test() ->
    [#rec2{}] = lists:map(fun map/1, [1]).

map(_X) ->
    #rec1{}.


With the above, I get the expected warning.  I've looked at lists.erl, and it doesn't look to be doing anything different.  It does have some -spec directives, but adding those in my code did not appear to help.

Any hints?

Cheers,

Steve

-- Steve Strong
@srstrong

Sent with Sparrow (http://www.sparrowmailapp.com/?sig)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20111114/43dced76/attachment.htm>


More information about the erlang-questions mailing list