A recent poster best left anonymous attempted to implement the factorial function like this:
f :: Int -> Int
f = fix f
This obviously didn't work out too well. But then I got to wondering: can I make it pass the type checker? What will its type reveal?
Indeed, it will type check given a more general type, thanks to polymorphic recursion:
By parametricity, we can immediately see that it must be bottom, and based on the definition of
fix
, it must be an infinite loop rather than an exception.chi comments, "For the same reason
f = bar f
will 'work' with anybar :: F a -> a
whereF a
is any type (which may depend ona
)". The definition looks like this:Again, the type signature is bogus by parametricity, since I can choose, for example,
f ~ Const Void
, at which point it is clear that the first argument is useless for producing the result.