Consider the following function:
f :: a -> Int
f x = (1 :: Int)
We might say that the type
First a question: Is the statement "all lists have length" a single statement or a series of statements "list1 has length", "list2 has length",...?
If you give the type of f
with explicit forall
, you get f :: forall a. a -> Int
. First of all, this is not "higher-kinded". We can do the following in GHCI:
λ> :set -XRankNTypes
λ> :k (forall a. a -> Int)
(forall a. a -> Int) :: *
So f
has a kind of *
.
Now, in Haskell, we can use ~
for type equality. We can set the following to check stuff in GHCI:
λ> :set -XImpredicativeTypes
λ> :set -XTypeFamilies
λ> :t undefined :: ((~) Int Int) => a
undefined :: ((~) Int Int) => a :: a
This shows that GHC figured out type equality for this example. Type inequality will give the following error:
λ> undefined :: ((~) (Int -> Int) (Int)) => a
:22:1:
Couldn't match expected type ‘Int’ with actual type ‘Int -> Int’
In the expression: undefined :: ((~) (Int -> Int) (Int)) => a
In an equation for ‘it’:
it = undefined :: ((~) (Int -> Int) (Int)) => a
Now using this method directly will prevent us from comparing the type of f
, but I found a slight variant that should work for our purposes:
λ> :t undefined :: forall a. ((a -> Int) ~ (Int -> Int)) => a
undefined :: forall a. ((a -> Int) ~ (Int -> Int)) => a :: Int
In other words, if f
is type-equivalent to g :: Int -> Int
, then a
must be Int. This is similar to x = y
, y = 0
so x = 0
. We don't have x = 0
until we specify y = 0
, until then we just have x = y
.
Maybe
is different because it has the following kind:
λ> :k Maybe
Maybe :: * -> *
Because we're using DataKinds
, we have :k (~) :: k -> k -> GHC.Prim.Constraint
, so we can do things like:
λ> :t undefined :: (~) Maybe Maybe => Int
undefined :: (~) Maybe Maybe => Int :: Int
λ> :k Either ()
Either () :: * -> *
λ> :t undefined :: (~) Maybe (Either ()) => Int
Couldn't match expected type ‘Either ()’ with actual type ‘Maybe’
To sum up, f :: forall a. a -> Int
makes as much sense as the statement "if you give me anything, I'll give you an Int". Could you translate the statement into a bunch of statements "if you give me a dog..", "if you give me a penny.."? Yeah, but it weakens the statement. At the end, decide precisely what you mean by the "same" and you get your answer.