Why can't Haskell resolve the kind of [[]] (A list of lists)?
Why isn't it simply * -> *, as I can give it a type like Int, and get [[Int]], which is of kind *.
views:
222answers:
2I think it's the same as with Maybe Maybe
, although in the latter case the reason is perhaps clearer: the "outer" type constructor expects to be passed a type of kind *
, but sees a type constructor of type * -> *
(the "inner" Maybe
/ []
) and complains. If I'm correct, this is not really a problem with the :kind
functionality of GHCi, but rather with finding the correct syntax to express the composition of higher-kinded type constructors.
As a workaround, something like
:kind forall a. [[a]]
:kind forall a. Maybe (Maybe a)
can be used (with the appropriate language extension turned on -- ExistentialQuantification
, I think -- to enable the forall
syntax).
If we desugar [[]]
as [] []
then it's obvious that it is poorly kinded because [] :: * -> *
.
If you actually wanted a "list of lists" you need to compose two type constructors of kind * -> *
. You can't do that without a little boilerplate because Haskell doesn't have a type-level lambda. You can do this though:
newtype Comp f g a = Comp { unComp :: f (g a) }
Now you can write:
type ListList = Comp [] []
And write functions using it:
f :: ListList Int -> ListList Int
f = Comp . map (map (+1)) . unComp
Functor composition like this has applications in several areas, notably Swierstra's "Data types a la carte"