Home > Back-end >  Kind product in haskell
Kind product in haskell

Time:02-22

Can I write a product kind for kind product of kinds without polluting the term level namespace ?

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}

data Pair a b = Pair a b

type family Proj1 (asd :: Pair a b) where
  Proj1 ('Pair a b) = a

type family Proj2 (asd :: Pair a b) where
  Proj2 ('Pair a b) = b

CodePudding user response:

Well, you can leave out the constructor:

data Pair a b

Now, Pair is both a type-level product:

x :: Pair a b
x = undefined

and a kind-level product:

type family Proj1 (x :: Pair a b)

with no associated term-level Pair.

It ends up being a little hard to do much with it. Since it's uninhabited as a type (no terms) and uninhabited as a kind (no types).

I think that's what @chepner was pointing out in the comment. Since the only way to define a new kind in Haskell is to define a new type and lift it, the only way to define a new kind without affecting the term-level namespace is to define an uninhabited new type and lift it to an uninhabited kind.

Note that, as soon as DataKinds is enabled, the kind-level product (,) automatically springs into existence, so if your worry is about adding to term-level namespace pollution, you can just use that one:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}

type family Proj1 (asd :: (a,b)) where
  Proj1 '(a,b) = a

type family Proj2 (asd :: (a,b)) where
  Proj2 '(a,b) = a

and in GHCi:

> :kind! Proj1 '(Int, String)
Proj1 '(Int,String) :: *
= Int
  • Related