我建议您使用StandaloneKindSignatures
:
..
{-# Language StandaloneKindSignatures #-}
type Id :: k -> k
type Id a = a
type Proxy :: k -> Type
data Proxy a = Proxy
type
PK :: k -> Type
type family
PK a where
PK Int = Char
PK @Type Int = Char
kind 参数是不可见的,但您可以在类型族(requires TypeApplications
)中显式编写它。
使用 GADT,您可以编写Proxy
type Proxy :: k -> Type
data Proxy a where
Proxy :: Proxy @k a
有一些建议允许在声明头中显示(种类)应用程序:
type Id :: k -> k
type Id @k a = a
type Proxy :: k -> Type
data Proxy @k a = Proxy
type
PK :: k -> Type
type family
PK @k a where
PK @Type Int = Char
我们可以在种类中使用“可见依赖量化”forall->
而不是(隐式)不可见forall.
type Id :: forall k -> k -> k
type Id k a = a
type Proxy :: forall k -> k -> Type
data Proxy k a = Proxy
type
PK :: forall k -> k -> Type
type family
PK k a where
PK Type Int = Char
之间的区别Proxy
,定义为统一数据类型(非 GADT 或半开玩笑:'legacy' 语法)或 GADT。除了k之外,它们是等效的(在旧 GHC 8.10 上测试)
- (
forall.
) 指定 = 可以用 指定TypeApplications
,但如果未指定则自动推断
- (
forall{}.
) inferred =TypeApplications
跳过它,不能直接指定
这适用于类型构造函数Proxy
和为消除歧义而命名的数据构造函数P
,因为它们都是多态的。Proxy
可以根据 的量化来指定Proxy @Nat 42
或推断:Proxy 42
k
Proxy :: forall (k :: Type). k -> Type
-- or
Proxy :: forall {k :: Type}. k -> Type
并且根据 中的量化P
,可以指定或推断k:P @Nat @42
P @42
P :: forall {k :: Type} (a :: k). Proxy @k a
P :: forall {k :: Type} (a :: k). Proxy a
-- or
P :: forall (k :: Type) (a :: k). Proxy @k a
P :: forall (k :: Type) (a :: k). Proxy a
这给出了几个结果
- k在两者中推断:
P @42 :: Proxy 42
( P @42 :: Proxy 42
)
data Proxy a = P
--
data Proxy a where
P :: Proxy a
- k在 ( ) 中指定但在( )中
Proxy
推断P
P @42 :: Proxy @Nat 42
data Proxy (a :: k) where
P :: Proxy a
--
type Proxy :: k -> Type
data Proxy a where
P :: Proxy a
Proxy
和P
( P @Nat @42 :: Proxy @Nat 42
)中指定的k
data Proxy (a :: k) = P
--
type Proxy :: k -> Type
data Proxy a = P
--
type Proxy :: forall k. k -> Type
data Proxy a = P
--
type Proxy :: forall k. k -> Type
data Proxy (a :: k) = P
--
type Proxy :: k -> Type
data Proxy a where
P :: Proxy @k a
我正在等待对量化和范围界定的许多新的和即将发生的变化尘埃落定,这可能已经过时了。