Haskell如何将类型信息带入值层?

How to bring type information into value level in Haskell?

我正在寻找在 Haskell 中将类型信息带入值级别的方法。

我知道将任何类型信息表示为值的一种方法是 Language.Haskell.TH.Type。 有什么方法可以实现一个函数,该函数采用 a 类型的 Proxy a 和 returns Language.Haskell.TH.Type(或表示任何类型的替代类型),如下所示?

如果您有更好的想法将类型信息作为不使用 Language.Haskell.TH.Type 的值,也请告诉我。

import Data.Proxy (Proxy)
import Language.Haskell.TH (Type, TypeQ)

-- |
-- >>> amazing (Proxy :: Proxy Bool)
-- ConT GHC.Types.Bool
--
-- >>> amazing (Proxy :: Proxy [String])
-- AppT ListT (ConT GHC.Base.String)
amazing :: Proxy a -> Type
amazing p = undefined

-- |
-- Or if above is impossible, how about this?
amazingQ :: Proxy a -> TypeQ
amazingQ p = undefined

我归结为找到您想使用该类型信息执行的操作。无论哪种情况,您可能会查看的模块都是 Data.Typeable and Data.Data。这些模块的中心是两个类型类(可通过 -XDeriveDataTypeable 导出)

class Typeable a where {...}
class Typeable a => Data a where {..}

正如@chi 所提到的,前者可以让您戳一个类型以查找有关它的信息。也就是说,需要注意的是,您需要 Typeable 的实例才能正常工作(尽管如果您确实需要,您可以开始制作这些孤儿实例......)。特别是,有 typeRep:

ghci> import Data.Typeable
ghci> typeRep (Proxy :: Proxy (Either (Maybe [Integer]) ((), Bool, Int)))
Either (Maybe [Integer]) ((), Bool, Int)

但是,如果您决定要使用类型信息来尝试查找它具有的值表示(即构造函数),您将需要查看 Data.Data.