When discussing Void
on Haskell Libraries mailing list, there was this remark:
Back in the day it used to be implemented by an
unsafeCoerce
at the behest of Conor McBride who didn't want to pay for traversing the wholeFunctor
and 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
Void
is uninhabited than anyFunctor
that holds only values of the typeVoid
is 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
Functor
instance that does not adhere to the functor laws (but is total):Now evaluating
wrong
results 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
Something
is any type that isn't a plain variable, then we cannot give a validFunctor
instance forF
. Thefmap
function would have to mapC
toC
in order to adhere to the identity law for functors. But we have to produce anF b
, for unknownb
. IfSomething
is anything but a plain variable, that isn't possible.