<div dir="ltr">what does a datatype with no constructors mean?<br><br>E.g.<br><br><pre>data RSAStruct<br>data EVP_PKEY<br>data EVP_CIPHER<br>data EVP_CIPHER_CTX<br>data EVP_MD_CTX<br>data EVP_MD<br>data BIGNUM<br><br></pre>
<br><br><div class="gmail_quote">On Mon, Jul 28, 2008 at 8:01 PM, Felipe Lessa <span dir="ltr">&lt;<a href="mailto:felipe.lessa@gmail.com">felipe.lessa@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
2008/7/28 Galchin, Vasili &lt;<a href="mailto:vigalchin@gmail.com">vigalchin@gmail.com</a>&gt;:<br>
<div class="Ih2E3d">&gt;&gt; and we&#39;re suggesting instead:<br>
&gt;&gt;<br>
&gt;&gt; newtype AIOCB = AIOCB (ForeignPtr AIOCB)<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; ^^^ I am somewhat new to Haskell. Not a total newbie! But what exactly<br>
&gt; does the above mean? Are the three references of &quot;AIOCB&quot; in different<br>
&gt; namespaces?<br>
<br>
</div>The first and the third are the type AIOCB, the second is the type<br>
constructor AIOCB. That is, it is equivalent (up to renaming) to<br>
<br>
newtype T = C (ForeignPtr T)<br>
<br>
Now, why use Type in Type&#39;s definition? It is obvious that if we were creating<br>
<br>
data T = D T<br>
<br>
it would be pretty useless, however the type that ForeignPtr requires<br>
is just a phantom type. In other words, the ForeignPtr will never use<br>
the C constructor.<br>
<br>
An analogy to C: if you have<br>
<br>
typeA *pa;<br>
typeB *pb;<br>
<br>
then of course pa and pb have different types, however their internal<br>
representation are the same: an integral type of 32/64 bits. The C<br>
compiler only uses the type to provide warnings, to know the fields&#39;<br>
offsets, the size of the structure, etc. The same goes for Haskell, if<br>
you have<br>
<br>
pa :: ForeignPtr A<br>
pb :: ForeignPtr B<br>
<br>
then both pa and pb have different types, but again they have the same<br>
internal representation. However, for example, if you allocate memory<br>
for pa via Storable then the compiler will find the correct sizeOf<br>
definition because will gave the type hint. The compiler also won&#39;t<br>
you let mix pa and pb like in [pa,pb].<br>
<br>
<br>
<br>
So, if you declare<br>
<br>
newtype T = C (ForeignPtr T)<br>
<br>
you are:<br>
<br>
1) Hiding the ForeignPtr from the users of your library if you don&#39;t export C.<br>
2) Having type safeness by using ForeignPtr T instead of something<br>
generic like ForeignPtr () -- the same as using typeA* instead of<br>
void*.<br>
3) Not needing to create a different type, like<br>
<br>
data InternalT = InternalT<br>
newtype T = C (ForeignPtr InternalT)<br>
<br>
<br>
Well.. did it help at all? =)<br>
<br>
--<br>
<font color="#888888">Felipe.<br>
</font></blockquote></div><br></div>