[Haskell-cafe] New OpenGL package: efficient way to convert datatypes?

Daniel Fischer daniel.is.fischer at web.de
Thu Mar 4 11:45:46 EST 2010


Am Donnerstag 04 März 2010 16:45:03 schrieb Nick Bowler:
> On 16:20 Thu 04 Mar     , Daniel Fischer wrote:
> > Yes, without rules, realToFrac = fromRational . toRational.
>
> <snip>
>
> > I think one would have to add {-# RULES #-} pragmas to
> > Graphics.Rendering.OpenGL.Raw.Core31.TypesInternal, along the lines of
> >
> > {-# RULES
> > "realToFrac/CDouble->GLdouble"  realToFrac x = GLdouble x
> > "realToFrac/GLdouble -> CDouble" realToFrac (GLdouble x) = x
> >   #-}
>
> These rules are, alas, *not* equivalent to fromRational . toRational.

But these rules are probably what one really wants for a [C]Double <-> 
GLdouble conversion.

>
> Unfortunately, realToFrac is quite broken with respect to floating point
> conversions, because fromRational . toRational is entirely the wrong
> thing to do.

"entirely"? For

realToFrac :: (Real a, Fractional b) => a -> b

I think you can't do much else that gives something more or less 
reasonable. For (almost?) any concrete conversion, you can do something 
much better (regarding performance and often values), but I don't think 
there's a generic solution.

> I've tried to start some discussion on the haskell-prime
> mailing list about fixing this wart.  In the interim, the OpenGL package
> could probably provide its own CDouble<=>GLDouble conversions, but sadly

s/could/should/, IMO.

> the only way to "correctly" perform Double<=>CDouble is unsafeCoerce.

Are you sure? In Foreign.C.Types, I find

{-# RULES
"realToFrac/a->CFloat"    realToFrac = \x -> CFloat   (realToFrac x)
"realToFrac/a->CDouble"   realToFrac = \x -> CDouble  (realToFrac x)

"realToFrac/CFloat->a"    realToFrac = \(CFloat   x) -> realToFrac x
"realToFrac/CDouble->a"   realToFrac = \(CDouble  x) -> realToFrac x
 #-}

, so if you have a

{-# RULES
"realToFrac/Double->Double" realToFrac = id :: Double -> Double
  #-}

(why isn't that in GHC.Real, anyway?), it should do the correct thing - not 
that it's prettier than unsafeCoerce.


More information about the Haskell-Cafe mailing list