The paper “System F with Type Equality Coercions” by Sulzmann, Chakravarty, and Peyton Jones illustrates the translation of Haskell’s newtype into System FC with the following example:
newtype T = MkT (T -> T)
As I understand it, barring unsafePerformIO, the only possible values of this type are MkT id and MkT undefined because of parametricity. I’m curious if there are some actual uses for this (or a similar) definition.
Parametricity is about the values of types with variables.
Thas no variables, so parametricity does not apply. Infact, T has many inhabitantsThe type
Tis an implementation of the Untyped Lambda Calculus, a universal formal system equivalent in power to a Turing machine. The three functions above (plusap) form the SKI calculus, an equivalent formal system.It is possible to encode any Haskell datatype into
T. Consider the type for natural numberswe can encode
NatintoTnow, you are partially correct though. There is no way in Haskell to write the inverse function of this (so far as I know). Which is really a shame. Although you can write a sort of psuedo inverse with the type
T -> IO Nat. Also, my understanding is the GHCs optimizer can die on recursivenewtypes(someone please correct me if I am wrong about this, because I would like to go back to using them).Instead, the type
with
which is the lambda calculus with exceptions, can be used in a fully invertable way.
In conclusion, in one sense
Tis not a useful type at all, but in another sense it is the most useful type of all.