2011-05-07 42 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