<html><head><meta http-equiv="Content-Type" content="text/html charset=gb2312"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Yes, you are right.<div class=""><br class=""><div class="">I get the warning after evaluate both modules at the same time.</div><div class=""><br class=""></div><div class="">The warning is:</div><div class="">%%%%</div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">MacBookPro:dialyzer by$ dialyzer opaque1.erl opaque2.erl </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  Checking whether the PLT /Users/by/.dialyzer_plt is up-to-date... yes</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  Proceeding with analysis...</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">opaque2.erl:5: Function test/0 has no local return</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">opaque2.erl:7: The created fun has no local return</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">opaque2.erl:7: The attempt to match a term of type </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">          opaque1:test_text() against the pattern </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">          [{F, _} | _] breaks the opacity of the term</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">opaque2.erl:7: The attempt to match a term of type </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">          opaque1:test_text() against the pattern </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">          [] breaks the opacity of the term</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">opaque2.erl:7: Fun application with arguments </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">         (X :: opaque1:test_text()) will never return since it differs in the 1st argument from the success typing arguments: </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">         ([any()])</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> done in 0m0.17s</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">done (warnings were emitted)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">MacBookPro:dialyzer by$ </span></div><div class="">%%%%</div><div class=""><br class=""></div><div class="">Thank you!</div><div class=""><br class=""></div><div class="">Kind Regards,</div><div class="">Yao</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">在 2019年12月28日,16:43,zxq9 <<a href="mailto:zxq9@zxq9.com" class="">zxq9@zxq9.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><div class="">On 2019/12/28 16:25, by wrote:<br class="">> %% opaque1.erl<br class="">> -module(opaque1).<br class="">> -export_type([test_text/0]).<br class="">> -opaquetest_text() :: [{atom(), number()}].<br class="">> -export([make_text/0]).<br class="">><br class="">> -spec make_text() ->test_text().<br class="">><br class="">> make_text() -><br class="">>      [{a,1}, {c,3}].<br class=""><br class="">[snip]<br class=""><br class="">> %% opaque2.erl<br class="">> -module(opaque2).<br class="">> -export([test/0]).<br class="">><br class="">> test() -><br class="">>     X = opaque1:make_text(),<br class="">>     [F||{F, _} <- X]. % This violates the abstraction<br class="">><br class="">> Run dialyzer on these two modules will produce:<br class="">> %%%%<br class="">> MacBookPro:dialyzer by$ dialyzer opaque1.erl<br class="">>    Checking whether the PLT /Users/by/.dialyzer_plt is up-to-date... yes<br class="">>    Proceeding with analysis... done in 0m0.12s<br class="">> done (passed successfully)<br class="">> MacBookPro:dialyzer by$<br class="">> %%%%<br class="">><br class="">> %%%%<br class="">> MacBookPro:dialyzer by$ dialyzer opaque2.erl<br class="">>    Checking whether the PLT /Users/by/.dialyzer_plt is up-to-date... yes<br class="">>    Proceeding with analysis...<br class="">> Unknown functions:<br class="">>    opaque1:make_text/0<br class="">>   done in 0m0.13s<br class="">> done (passed successfully)<br class="">> MacBookPro:dialyzer by$<br class="">> %%%%<br class="">><br class="">> Am I missing something?<br class="">Two things:<br class="">1- You need to dialyze BOTH modules in the same run or else Dialyzer cannot see the typespecs in opaque1.erl while it is evaluating opaque2.erl<br class="">2- You can write code that violates opaque types, though I believe Dialyzer will issue a warning about it if you evaluate both at once.<br class=""><br class="">-Craig<br class=""></div></div></blockquote></div><br class=""></div></div></div></body></html>