haskell 中的商品

Kind product in haskell

我可以为 kind product of kinds 编写一个 product kind 而不会污染 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

嗯,你可以省略构造函数:

data Pair a b

现在,Pair 既是 type-level 产品:

x :: Pair a b
x = undefined

和一个 kind-level 产品:

type family Proj1 (x :: Pair a b)

没有关联 term-level Pair.

最终用它做很多事情有点困难。因为它作为一种类型无人居住(无术语)并且作为一种无人居住(无类型)。

我认为这就是@chepner 在评论中指出的内容。由于在 Haskell 中定义新种类的唯一方法是定义一个新类型并将其提升,因此在不影响 term-level 命名空间的情况下定义新种类的唯一方法是定义一个无人居住的新类型并且把它抬到一个无人居住的地方。

请注意,一旦启用 DataKinds,kind-level 产品 (,) 就会自动出现,所以如果您担心 添加 到 term-level 命名空间污染,你可以只使用那个:

{-# 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

在 GHCi 中:

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