[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