Paramametrically polymorphic functions
Consider the following function:
f :: a -> Int
f x = (1 :: Int)
We might say that the type of f
is a -> Int
, and that f
therefore is of a "polymorphic" type.
Which of the following is the most accurate way to think about f
?
There is in fact a single
f
of typea -> Int
. It can be used, however, as anf :: Int -> Int
, as anf :: Double -> Int
, and so forth.Literally speaking, the type of
f
is NOTa -> Int
. Indeed, that is just a shorthand way of saying that there is a family of functionsf
whose type is concrete (i.e., there is anf :: Int -> Int
, anf :: Double -> Double
, and so forth; moreover, each of these functions is distinct from each other).
Higher Kinded Types
Similarly, we can consider the following type declaration:
data Maybe a = Just a | Nothing
And ask which of the two views is more correct:
There is no single type
Maybe
; indeed, there is merely a family of concrete types (Maybe Int
,Maybe String
, etc) and nothing more.There is in fact a single type
Maybe
. This type is a higher-kinded type. When we say that it is a "type" we mean it literally (not as a shorthand for (1)). It just so happens that we can also writeMaybe Int
,Maybe Double
, and so forth to generate distinct types (which happen to be concrete). But, at the end of the day (i.e.):Maybe
,Maybe Int
, andMaybe String
denote three distinct types, two of which are concrete and one of which is higher-kinded.
Question Summary
In Haskell, are "higher-kinded types" really types? Or are only concrete types "the real types", and when we speak of "higher-kinded types" we are merely denoting a family of concrete types. Moreover, do paramametrically polymorphic functions denote functions of a single type, or do they merely denote a collection functions of concrete types (and nothing more)?