I saw Inverse of the absurd function earlier today, and while it's clear to me that any possible implementation of drusba :: a -> Void
will never terminate (after all, it's impossible to construct Void
), I don't understand why the same isn't true of absurd :: Void -> a
. Consider the GHC implementation:
newtype Void = Void Void
absurd :: Void -> a
absurd a = a `seq` spin a where
spin (Void b) = spin b
spin
, it seems to me, is endlessly unraveling the infinite series of Void
newtype wrappers, and would never return even if you could find a Void
to pass it. An implementation that would be indistinguishable would be something like:
absurd :: Void -> a
absurd a = a `seq` undefined
Given that, why do we say that absurd
is a proper function that deserves to live in Data.Void, but
drusba :: a -> Void
drusba = undefined
is a function that cannot possibly be defined? Is it something like the following?
absurd
is a total function, giving a non-bottom result for any input in its (empty) domain, whereasdrusba
is partial, giving bottom results for some (indeed all) inputs in its domain.