module Data.Floating.Types (
Double(..), Float(..), FloatConvert(..)
) where
import Prelude hiding (Double, Float)
import qualified GHC.Exts as GHC
import GHC.Integer
import GHC.Prim
import Foreign.C
import Data.Ratio
import Unsafe.Coerce
data Double = D# Double#
data Float = F# Float#
newtype FuckFFIDouble = FuckD Double
newtype FuckFFIFloat = FuckF Float
class FloatConvert a b where
toFloating :: a -> b
instance FloatConvert Double CDouble where
toFloating = unsafeCoerce . FuckD
instance FloatConvert CDouble Double where
toFloating f = let FuckD x = unsafeCoerce f in x
instance FloatConvert Float CFloat where
toFloating = unsafeCoerce . FuckF
instance FloatConvert CFloat Float where
toFloating f = let FuckF x = unsafeCoerce f in x
instance FloatConvert Double Float where
toFloating (D# x) = F# (double2Float# x)
instance FloatConvert Float Double where
toFloating (F# x) = D# (float2Double# x)
instance FloatConvert Integer Double where
toFloating x = D# (doubleFromInteger x)
instance FloatConvert Integer Float where
toFloating x = F# (floatFromInteger x)
instance Real a => FloatConvert a Double where
toFloating x = D# (num /## denom) where
!(D# num) = toFloating . numerator . toRational $ x
!(D# denom) = toFloating . denominator . toRational $ x
instance Real a => FloatConvert a Float where
toFloating x = F# (divideFloat# num denom) where
!(F# num) = toFloating . numerator . toRational $ x
!(F# denom) = toFloating . denominator . toRational $ x
instance FloatConvert a a where
toFloating = id