【问题标题】:Haskell -- get TypeRep from concrete type instanceHaskell -- 从具体类型实例中获取 TypeRep
【发布时间】:2011-08-20 22:32:37
【问题描述】:
我想用这个类型签名写一个函数:
getTypeRep :: Typeable a => t a -> TypeRep
TypeRep 将是 a 的类型表示,而不是 t a 的类型表示。也就是说,编译器应该在任何调用站点 [to getTypeRep] 自动返回正确的类型表示,这将具有 a 的具体类型。
为了添加一些上下文,我想创建一个“动态类型”数据类型,它会记住顶级类型,但不会记住它的参数。比如我想把MyClass a变成Dynamic MyClass,上面的函数会用来创建Dynamic MyClass的实例,里面存放着a类型参数的表示a。
【问题讨论】:
标签:
haskell
types
typeclass
dynamic-typing
【解决方案1】:
那么,如何使用作用域类型变量来选择内部组件:
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Dynamic
import Data.Typeable
getTypeRep :: forall t a . Typeable a => t a -> TypeRep
getTypeRep _ = typeOf (undefined :: a)
为我工作:
*Main> getTypeRep (Just ())
()
*Main> getTypeRep (Just 7)
Integer
*Main> getTypeRep ([True])
Bool
有趣的设计。
【解决方案2】:
关于 Don 的解决方案,请注意代码很少需要 ScopedTypeVariables。它只是使解决方案更清洁(但便携性较差)。没有作用域类型的解决方案是:
{-# LANGUAGE ExplicitForAll #-}
import Data.Typeable
helper :: t a -> a
helper _ = undefined
getTypeRep :: forall t a. Typeable a => t a -> TypeRep
getTypeRep = typeOf . helper