[Haskell-cafe] coercing D a to D b

Joachim Breitner mail at joachim-breitner.de
Thu Dec 14 15:16:10 UTC 2017


Am Mittwoch, den 13.12.2017, 21:34 -0800 schrieb Evan Laforge:
> Given:
> data D a = A a | B Int Char
> dmapNoCoerce :: (a -> b) -> D a -> D b
> dmapNoCoerce f (A a) = A (f a)
> dmapNoCoerce _ (B i c) = B i c
> I have to reconstruct a B change it from D a to D b.  But at the lower level,
> couldn't this be implemented as a type cast?  What prevents such an
> optimization?
> I can write this as
> dmapCoerce :: (a -> b) -> D a -> D b
> dmapCoerce f (A a) = A (f a)
> dmapCoerce _ b@(B {}) = Unsafe.Coerce.unsafeCoerce b
> From the core, it looks like dmapCoerce indeed has a cast with no allocation,
> while dmapNoCoerce allocates a new B.
> It seems to work, but is it safe?  Is there a more principled way to do it?
> I can't convince Data.Coerce to cooperate, presumably because 'a' and 'b' are
> not coercible themselves, and it doesn't believe me if I try to tell it the
> type role is phantom.

this coercion is not possible in Core, because Core’s type system is
not expressive enough (at least now…). But luckily, at the STG level
this optimization is possible, see

This is probably in 8.2.


Joachim Breitner
  mail at joachim-breitner.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20171214/d53749eb/attachment.sig>

More information about the Haskell-Cafe mailing list