> But below I do not understand your reasoning.
Given a datatype
data D = D Int
I call Int the type you're constructing D with, however the type of the constructor itself is Int -> D
In ghc haskell there is another way of defining the same type using GADTs alongside the above "haskell98" way:
data D where
D :: Int -> D
Notice how here we are explicitly typing the constructor.
The haskell98 way defines what your datatype D is isomorphic to - here it is Int, whereas the GADT way defines how to construct a D.
The problem haskell developers faced was that in order to use the haskell98 way for existentials they would've had to introduce an 'exists' quantifier, which would mess up a boatload of things in the type theory. Instead they introduced this forall hack that doesn't define an isomorphic type, rather it indicates that we are defining a way of constructing an existential.
I find this ugly because it breaks the isomorphism that the = sign indicates in a haskell98 definition.
The GADT way on the other hand is defining ways of construction, so a definition like:
data D2 where
D2 :: a -> D2
makes perfect sense
> Is there around a good textbook for "beginners", with full proofs, but only the essential ones?
Types and Programming Languages from Benjamin Pierce is a good one. I also plan to upload a short video lecture series from Harper on type theory (it assumes minimal knowledge of logic), i'll send you a link when it's up.