2011-05-07 44 views
11

得到TypeRep我想写这种类型的签名功能:哈斯克尔 - 从具体类型实例

getTypeRep :: Typeable a => t a -> TypeRep 

其中TypeRep将是一个类型表示,不吨一个。也就是说,编译器应该在任何呼叫站点自动返回正确的类型表示[至getTypeRep],这将具有a的具体类型。

要添加一些上下文,我想要创建一个“动态类型”的数据类型,其扭曲将记住顶级类型,但不是它的参数。例如,我想打开MyClass的一个动态MyClass的,并且上述功能将被用于创建存储类型参数一个的表示动态MyClass的的实例。

回答

9

那么,如何使用范围的类型变量来选择内部组件:

{-# 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 

有趣的设计。

8

在唐的解决方案的切线注意,请注意代码很少需要 ScopedTypeVariables。它只是使解决方案更清洁(但便携性更低)。无作用域类型的解决方案是:

{-# LANGUAGE ExplicitForAll #-} 
import Data.Typeable 

helper :: t a -> a 
helper _ = undefined 

getTypeRep :: forall t a. Typeable a => t a -> TypeRep 
getTypeRep = typeOf . helper