Skip to content

Instantly share code, notes, and snippets.

Created February 9, 2014 14:43
Show Gist options
  • Save nh2/8900071 to your computer and use it in GitHub Desktop.
Save nh2/8900071 to your computer and use it in GitHub Desktop.
Discussion on #haskell about realToFrac performance
Does realToFrac compile to a no-op for (CFloat <-> Float / CDouble <-> Double)?
(14:27:30) kosmikus: nh2: it'll be a noop in many situations. CDouble normally is a newtype wrapper around Double. There are GHC Rule pragmas that'll turn realToFrac between Double and CDouble into a realToFrac between Double and Double by applying the constructor. Applying the constructor is a no-op, and there's a Double/Double instance having id as implementation.
(14:28:17) kosmikus: nh2: that being said, it's known that while simple applications of newtype constructors are newtypes, that doesn't translate to all contexts (such as mapping the constructor over a datastructure, for example)
(14:28:55) FreeFull: kosmikus: realToFrac isn't part of a typeclass though, it is defined as realToFrac = fromRational . toRational
(14:30:37) kosmikus: FreeFull: hm, you're right, I've been looking at the wrong place. let's check again.
(14:32:38) nh2: kosmikus, FreeFull: I really hope that realToFrac has rewrite rules for Double/CDouble and Float/CFloat (since *all* FFI tutorials use it), but I can't find the rules in the code
(14:33:06) kosmikus: FreeFull, nh2: ok, I was wrong about the type class. realToFrac has a rewrite rule for Double/Double mapping to id though (in GHC.Float).
(14:33:47) kosmikus: FreeFull, nh2: so it's still a combination of two rewrite rules which will say that from Double to CDouble you just have to apply the newtype constructor.
(14:33:58) nh2: kosmikus: and that works through the newtype, I see
(14:36:43) kosmikus: nh2: compile "print (realToFrac (2 :: Double) :: CDouble)" with -O -ddump-rule-firings
(14:37:00) kosmikus: nh2: then you can see that both realToFrac/a->CDouble and realToFrac/Double->Double fire
(14:37:30) kosmikus: one is defined in Foreign.C.Types, the other in GHC.Float
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment