开发者

Haskell -- get TypeRep from concrete type instance

I want to write a function with this type signature:

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

where the TypeRep will be the type representation for a, not fo开发者_JAVA百科r t a. That is, the compiler should automatically return the correct type representation at any call sites [to getTypeRep], which will have concrete types for a.

To add some context, I want to create a "Dynamic type" data type, with the twist that it will remember the top-level type, but not its parameter. For example, I want to turn MyClass a into Dynamic MyClass, and the above function will be used to create instances of Dynamic MyClass that store a representation of the type parameter a.


Well, how about using scoped type variables to select the inner component:

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}

import Data.Dynamic
import Data.Typeable

getTypeRep :: forall t a . Typeable a => t a -> TypeRep
getTypeRep _ = typeOf (undefined :: a)

Works for me:

*Main> getTypeRep (Just ())
()
*Main> getTypeRep (Just 7)
Integer
*Main> getTypeRep ([True])
Bool

Interesting design.


On a tangential note to Don's solution, notice that code rarely require ScopedTypeVariables. It just makes the solution cleaner (but less portable). The solution without scoped types is:

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

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

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


This function (now) exists in Data.Typeable typeRep

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜