Joachim Breitner's Homepage
Adding safe coercions to Haskell
Yesterday, I pushed my first sizable contribution to GHC, the Haskell compiler. The feature solves the problem that newtypes are not always free: If we have newtype Age = MkAge Int
, then we have all learned that the Age
function has zero run-time cost. But if the Int
that we want to convert is inside another type, the conversion is no longer free: Converting a Maybe Int
to a Maybe Age
using, for example, fmap Age
, will cause time and space overhead at runtime, and there was no way around it. Well, there is unsafeCoerce
, but really, that ought to be avoided.
So after some discussion with and encouragement of Simon Peyton Jones at RDP in Eindhoven this year I worked on a design (which was developed, as far as I know, by Simon, Roman Cheplyaka, Stephanie Weirich, Richard Eisenberg and me). In GHC 7.8, there will be a function coerce :: Coercible a b => a -> b
that works, from the user point of view, like unsafeCoerce
(i.e. no run-time cost), but with the big difference that it will only typecheck if the compiler can infer that it indeed is safe to coerce between a
and b
. So it will derive Coercible Age Int
, and Coercible Int Age
, and Coercible (Maybe Age) (Maybe Int)
and even stuff like Coercible (Int -> Age) (Age -> Int)
, but not Coercible Int Bool
. It will also not coerce between Age
and Int
if the constructor MkAge
is not exported, to respect module boundaries.
Under the hood this relies on the also new feature of roles, which were solved to make the previously unsafe GeneralizedNewtypeDeriving
feature safe again, and which also guarantee that coerce
is indeed as safe as the name suggests.
The feature will come with 7.8, but not “fully advertised”, so things might change again for 7.10, and bugs with the feature may not necessarily qualify to be fixed in further 7.8.x releases, so beware. It also does not automatically convert fmap Age
into coerce
, but it is a step in that direction.
Comments
The only tedious part is we'll have to rename our own `coerce` combinator. ;)
Have something to say? You can post a comment by sending an e-Mail to me at <mail@joachim-breitner.de>, and I will include it here.