Until now, i have thought that the (->)
type has the kind * -> * -> *
. But what confuses me is that it also works for unlifted types (e. g. Int#
).
I inspected the type with ghci and got * -> * -> *
like expected.
This was all I could figure out but I don't understand how the arrow is kind polymorphic.
ghci> :k (->)
(->) :: * -> * -> *
ghci> :k Int#
Int# :: TYPE IntRep
ghci> :k (->) Int#
(->) Int# :: * -> *
Indeed the kind is polymorphic over any RuntimeRep
, that’s just hidden by default. There are a few flags that enable showing the details.
λ :set -fprint-explicit-foralls
λ :set -fprint-explicit-kinds
λ :set -fprint-explicit-runtime-reps
λ :set -XNoStarIsType
λ :kind (->)
(->) :: forall {q :: GHC.Types.RuntimeRep}
{r :: GHC.Types.RuntimeRep}.
TYPE q -> TYPE r -> Type