Proposal: refactor Arrow class

Edward Kmett ekmett at
Wed Jan 9 08:57:02 CET 2013

It is about functoriality in the sense that by providing a custom
implementation for the unsafe method that uses unsafeCoerce you are
asserting that your Functor really is one and doesn't do any GADT-like
tricks on the functor argument and structurally complies with the laws.

It lets you lift core `cast`'s out over the functorial argument, which
isn't something I can do from outside of the class. If I tried to write
something where the end user hands me an arbitrary Functor (or Profunctor)
and I unsafeCoerce to cast, this would expose unsafeCoerce to the end user.

The implementation trick is to place these extra methods in the class but
hidden in an explicitly Unsafe module and with default definitions that are
correct but slow.

Then the provider of the functor-like class can explicitly import that
module, and implement the methods, and mark his module Trustworthy. He
hasn't exposed unsafeCoerce to the end user, they have to import an
explicitly Unsafe module to get access to it, incurring the obligation
themselves to provide something that is operationally id or a cast.

This enables you to have the efficient implementation but guarded by an
explicitly Unsafe module so the end user has to import that to get the
efficient functionality, but you can discharge your obligations locally.

Similarly you can discharge the obligation about the representation of the
operation you are passing at the use site. This means that you can reason
about these separately.

In theory a similar operation could be exposed for Functor in a similar
Unsafe module permitting a more efficient implementation of vacuous to be
implemented soundly in Data.Void preserving sharing and changing the
asymptotics of the casting from f Void for data types where the end user is
willing to incur the reasoning obligation, but frankly, I'm not willing to
fight that battle today.


On Tue, Jan 8, 2013 at 8:16 PM, Ross Paterson <ross at> wrote:

> Is the Unsafe module all about getting efficient conversions between
> types that have the same representations due to embedded newtypes?
> (If so, the issue is not about functoriality.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list