<div>First a bit of background.  Sometimes I would like to be able to create unboxed arrays of CFloats and GLfloats.  Both of these are defined as newtypes around types that can be unboxed (e.g., Float).  I&#39;m assuming GHC here.</div>
<div><br></div><div>As far as I can tell, the newtyping is there to help programmers pick a representation that matches the C compiler&#39;s representation on their platform without having to use CPP in their Haskell code.</div>
<div><br></div><div>Would it be possible to add instances like these?</div><div><br></div><div>instance MArray (STUArray s) GLfloat (ST s)</div><div>instance MArray IOUArray GLfloat IO</div><div><br></div><div><meta charset="utf-8"><div>
instance MArray (STUArray s) CFloat (ST s)</div><div>instance MArray IOUArray CFloat IO</div></div><div><br></div><div>I would also want instances for the other C types that map to Haskell types that are unboxed and the other GL types too.</div>
<div><br></div><div>For example, in my program I imported all the right libraries and added this instance as an experiment:</div><div><div>instance MArray (STUArray s) GLfloat (ST s) where</div><div>    {-# INLINE getBounds #-}</div>
<div>    getBounds (STUArray l u _ _) = return (l,u)</div><div>    {-# INLINE getNumElements #-}</div><div>    getNumElements (STUArray _ _ n _) = return n</div><div>    {-# INLINE unsafeNewArray_ #-}</div><div>    unsafeNewArray_ (l,u) = unsafeNewArraySTUArray_ (l,u) fLOAT_SCALE</div>
<div>    {-# INLINE newArray_ #-}</div><div>    newArray_ arrBounds = newArray arrBounds 0</div><div>    {-# INLINE unsafeRead #-}</div><div>    unsafeRead (STUArray _ _ _ marr#) (I# i#) = ST $ \s1# -&gt;</div><div>        case readFloatArray# marr# i# s1# of { (# s2#, e# #) -&gt;</div>
<div>        (# s2#, unsafeCoerce (F# e#) #) }</div><div>    {-# INLINE unsafeWrite #-}</div><div>    unsafeWrite (STUArray _ _ _ marr#) (I# i#) e = ST $ \s1# -&gt;</div><div>        let F# e# = unsafeCoerce e in</div><div>
        case writeFloatArray# marr# i# e# s1# of { s2# -&gt;</div><div>        (# s2#, () #) }</div></div><div><br></div><div>I had to use an unsafeCoerce because the constructor for GLfloat is not exposed, and realToFrac has terrible performance because the following rules (suggested by Andy Gill) are missing from the OpenGL bindings:</div>
<div><div>{-# RULES &quot;realToFrac/a-&gt;GLfloat&quot; realToFrac = \x -&gt; GLfloat (realToFrac x) #-}</div><div>{-# RULES &quot;realToFrac/GLfloat-&gt;a&quot; realToFrac = \(GLfloat x) -&gt; realToFrac x #-}</div></div>
<div><br></div><div>Even if I had those rules, I would still need to get access to the underlying representation (the e#) to have the right kind.  GLfloat is defined in terms of CFloat which is defined in terms of other things.  On my machine, CFloat happens to correspond to Float, although in general this need not be the case.  So to do this instance correctly I would need to know, in general, what the underlying type is for CFloat.  I think that means I would need to use the same macros as GHC, although I don&#39;t think that requires this instance to appear in base.  I could just borrow the macros once I figure out the corresponding instance for CFloat.</div>
<div><br></div><div>While the GLfloat instances don&#39;t need to be in base, the CFloat instance probably should be in base.  Is this something I should make a library proposal for and submit patches?  Is there an easier way to get these instances?  Has someone already done this?</div>
<div><br></div><div>Thanks,</div><div>Jason</div>