polykinded 类型的应用程序是单射的吗?
当我们启用PolyKinds
时,我们知道这f a ~ g b
意味着f ~ g
和a ~ b
吗?
动机
在尝试回答另一个问题时,我将问题减少到仅在PolyKinds
启用时收到以下错误的程度。
Could not deduce (c1 ~ c)
from the context ((a, c z) ~ (c1 a1, c1 b))
如果多类应用是单射的,我们可以推论c1 ~ c
如下。
(a, c z) ~ (c1 a1, c1 b)
(a,) (c z) ~ (c1 a1,) (c1 b) {- switch to prefix notation -}
c z ~ c1 b {- f a ~ g b implies a ~ b -}
c ~ c1 {- f a ~ g b implies f ~ g -}
c1 ~ c {- ~ is reflexive -}
类型应用是单射的
在 Haskell 中,类型应用程序是单射的。如果f a ~ g b
那么f ~ g
和a ~ b
。我们可以通过编译以下代码向自己证明这一点
{-# LANGUAGE GADTs #-}
import Control.Applicative
second :: a -> a -> a
second _ = id
typeApplicationIsInjective :: (Applicative f, f a ~ g b) => f a -> g b -> f b
typeApplicationIsInjective fa gb = second <$> fa <*> gb
类型应用程序不是单射的
类型应用程序的类型不是单射的。如果我们考虑以下,其中有 kind (* -> *) -> *
。
newtype HoldingInt f = HoldingInt (f Int)
我们可以问ghci,(* -> *) -> *
当应用于某种类型时,某种类型的东西有什么类型* -> *
,即*
> :k HoldingInt
HoldingInt :: (* -> *) -> *
> :k Maybe
Maybe :: * -> *
> :k HoldingInt Maybe
HoldingInt Maybe :: *
这与* -> *
应用于某种事物的某种事物相同*
> :k Maybe
Maybe :: * -> *
> :k Int
Int :: *
> :k Maybe Int
Maybe Int :: *
因此,从 借用语法KindSignatures
,第一组种类签名暗示第二组中的任何内容是不正确的。
f :: kf, g :: kg, a :: ka, b :: kb, f a :: k, g b :: k
g :: kf, f :: kg, b :: ka, a :: kb