realToFrac doesn't sanely convert between floating types
As far as I can tell, the only way to convert between floating types in Haskell is to use realToFrac. Unfortunately, this function does some insane mangling of values when converting. Some examples:
realToFrac (0/0 :: Double) :: Double --> -Infinity realToFrac (-1/0 :: Float) :: Double --> -3.402823669209385e38 realToFrac (-0 :: Double) :: CDouble --> 0.0
The last item illustrates an important point: it is impossible to convert a value from Double to CDouble without potentially changing it. This makes it difficult or impossible to use the FFI to call any functions with floating point parameters/return values.
Using a combination of unsafeCoerce (to shoehorn Double values in/out of CDoubles) and some functions written in C (to perform float<=>double), I was able to work around these problems, but that hardly seems like a nice solution.