
On Wed, Jan 09, 2013 at 07:57:02AM +0000, Edward Kmett wrote:
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.
You could achieve the same effects by splitting off (.#) and (#.) into a subclass, couldn't you? It would just mean more instance declarations.