有可能在Haskell中获得类型构造函数的类型吗?
我正在处理Data.Typeable,尤其是我希望能够生成特定类型的正确类型(比如有可能在Haskell中获得类型构造函数的类型吗?,haskell,type-kinds,Haskell,Type Kinds,我正在处理Data.Typeable,尤其是我希望能够生成特定类型的正确类型(比如*)。我遇到的问题是TypeRep允许我们执行以下操作(使用GHC 7.8中的版本): 这里的badType在某种意义上是类型Maybe-Maybe的表示,它不是任何类型的有效类型: > :k Maybe (Maybe) <interactive>:1:8: Expecting one more argument to ‘Maybe’ The first argument of
*
)。我遇到的问题是TypeRep允许我们执行以下操作(使用GHC 7.8中的版本):
这里的badType
在某种意义上是类型Maybe-Maybe的表示,它不是任何类型的有效类型:
> :k Maybe (Maybe)
<interactive>:1:8:
Expecting one more argument to ‘Maybe’
The first argument of ‘Maybe’ should have kind ‘*’,
but ‘Maybe’ has kind ‘* -> *’
In a type in a GHCi command: Maybe (Maybe)
并且有一个函数kindOf
和kindOf Int=Star
(可能真的kindOf(Proxy::Proxy Int)=Star
)和kindOf Maybe=KFun Star
,这样我就可以“检查”我的TypeRep值
我想我可以用一个类似于
Typeable
的多类typeclass手动完成这项工作,但我更愿意不必为所有内容编写自己的实例。我也不希望回到GHC7.6,而是使用这样一个事实:对于不同类型的可键入类型,有单独的类型类。我对从GHC获取此信息的方法持开放态度。我们可以获得类型的类型,但我们需要在GHC中抛出大量的语言扩展来实现这一点,包括(在本例中)超过可疑的不可判定实例
和AllowAmbiguousTypes
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
import Data.Proxy
instance (Kindable a, Kindable (f a)) => Kindable f where
kindOf _ = KFun (kindOf (Proxy :: Proxy a)) (kindOf (Proxy :: Proxy (f a)))
将您的定义用于KindRep
data KindRep = Star | KFun KindRep KindRep
我们定义了Kindable
可以确定其种类的事物的类别
class Kindable x where
kindOf :: p x -> KindRep
第一个例子很简单,任何类型的*
都是Kindable
:
instance Kindable (a :: *) where
kindOf _ = Star
要得到更高级的类型是很难的。我们试着说,如果我们能找到它的论点的类型,以及把它应用到论点的结果,我们就能找出它的类型。不幸的是,因为它没有参数,我们不知道它的参数是什么类型;这就是为什么我们需要AllowAmbiguousTypes
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
import Data.Proxy
instance (Kindable a, Kindable (f a)) => Kindable f where
kindOf _ = KFun (kindOf (Proxy :: Proxy a)) (kindOf (Proxy :: Proxy (f a)))
结合起来,这些定义允许我们写下
kindOf (Proxy :: Proxy Int) = Star
kindOf (Proxy :: Proxy Maybe) = KFun Star Star
kindOf (Proxy :: Proxy (,)) = KFun Star (KFun Star Star)
kindOf (Proxy :: Proxy StateT) = KFun Star (KFun (KFun Star Star) (KFun Star Star))
只是不要像Proxy
kindOf (Proxy :: Proxy Proxy)
幸运的是,这只会在有限的时间内导致编译器错误。
typeOf1
和Typeable1
(和朋友)仍然从数据导出。Typeable
。。。它们在7.8FYI中可用,我所遇到的大多数Haskell硕士认为AllowAmbiguousTypes
可能有点阴暗,但这是否会让推断有点不可靠?