<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 08/25/2016 10:57 PM, Daniel
Abrahamsson wrote:<br>
</div>
<blockquote
cite="mid:CAJL2zxX+S1S48=RW8CPmyybSHym+kA5EputyVa4va1jZxSbRRg@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif">You can achieve
something close to what you are after by using opaque types.
Partly re-using your original example:</div>
<div class="gmail_default"
style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div class="gmail_default" style="">
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-module(string_with_case).</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-opaque lowercase() :: string().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-opaque uppercase() :: string().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-type anycase() :: lowercase() |
uppercase() | string().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-export_type([ lowercase/0</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> , uppercase/0</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> ]).</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-export([ uppercase/1</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> , lowercase/1</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> , need_lower/1</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> , concat/2</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"> ]).</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-spec lowercase(anycase()) ->
lowercase().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">lowercase(Str) ->
string:to_lower(Str).</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-spec uppercase(anycase()) ->
uppercase().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">uppercase(Str) ->
string:to_upper(Str).</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-spec need_lower(lowercase()) ->
ok. </font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">need_lower(_Lower) -> ok. </font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">-spec concat(anycase(), anycase())
-> string().</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">concat(A, B) -> A ++ B.</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">Note that these two (maybe in your
eyes valid) examples will NOT pass dialyzer:</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif"><br>
</font></div>
<div class="gmail_default" style=""><font face="arial,
helvetica, sans-serif">string_with_case:need_lower("example").
% FAILS: Breaks opaqueness of
string_with_case:lowercase().</font></div>
<div style="font-family:arial,helvetica,sans-serif"><br>
</div>
<div style="font-family:arial,helvetica,sans-serif">string_with_case:lowercase("test")
++ "mixing". % FAILS: Breaks opaqueness of
string_with_case:lowercase().</div>
<div><br>
</div>
<div>In other words, all operations involving types
uppercase() or lowercase() must take place inside the
string_with_case module.</div>
<div>If you need to operate on a lowercase() as if it were a
string outside the string_with_case module, you must provide
a to_string function:</div>
<div><br>
</div>
<div>-spec to_string(anycase()) -> string().</div>
<div>to_string(X) -> X.</div>
<div><br>
</div>
<div>This of course means you would have to call the
lowercase/1 or uppercase/1 functions again to convert it
back, should you need to</div>
<div>use the "variant/sort specific" functions of
string_with_case on the result. This is however necessary to
maintain the guarantees you are trying to achieve.</div>
<div><br>
</div>
<div>//Daniel</div>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
</blockquote>
<tt>This approach works in a closed-system that only relies on the
opaque types. If the opaque types are not always used as opaque
types, i.e., in a way that depends on it being a list of integers,
then that will just generate dialyzer errors. Also, the fact
remains that it does not actually check the contents of the list,
so this approach depends on the developer always using the opaque
types in the proper way (i.e., it isn't as if development errors
with the opaque types will be easily caught based on the contents
of the list of integers). Since software is normally not
developed in complete isolation, requiring complete isolation for
a solution is not helpful for any system that might want to grow
in the future.</tt><br>
</body>
</html>