When discussing Void on Haskell Libraries mailing list, there was this remark:
Back in the day it used to be implemented by an
unsafeCoerceat the behest of Conor McBride who didn't want to pay for traversing the wholeFunctorand replacing its contents, when the types tell us that it shouldn't have any. This is correct if applied to a proper Functor, but subvertible in the presence of GADTs.
The documentation for unsafeVacuous also says:
If
Voidis uninhabited than anyFunctorthat holds only values of the typeVoidis holding no values.This is only safe for valid functors that do not perform GADT-like analysis on the argument.
How would such a mischievous GADT Functor instance look like? (Using only total functions of course, without undefined, error etc.)
It's certainly possible if you're willing to give a
Functorinstance that does not adhere to the functor laws (but is total):Now evaluating
wrongresults in a run-time exception, even though the type-checker considers it total.Edit
Because there's been so much discussion about the functoriality, let me add an informal argument why a GADT that actually performs analysis on its argument cannot be a functor. If we have
where
Somethingis any type that isn't a plain variable, then we cannot give a validFunctorinstance forF. Thefmapfunction would have to mapCtoCin order to adhere to the identity law for functors. But we have to produce anF b, for unknownb. IfSomethingis anything but a plain variable, that isn't possible.