2011-05-07 17 views
11

Chcę napisać funkcję z tego podpisu Typ:Haskell - dostać TypeRep od typu konkretnej instancji

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

gdzie TypeRep będzie reprezentacja typu dla , nie dla T a. Oznacza to, że kompilator powinien automatycznie zwracać poprawną reprezentację typów w dowolnych miejscach połączeń [do getTypeRep], które będą miały konkretne typy dla a.

Aby dodać jakiś kontekst, chcę utworzyć typ danych "Typ dynamiczny", z tym, że zapamięta typ najwyższego poziomu, ale nie jego parametr. Na przykład, chcę włączyć MojaKlasa do Dynamiczny MojaKlasa, a powyższa funkcja będzie używana do tworzenia wystąpień Dynamiczny MojaKlasa które przechowują reprezentację parametru type .

Odpowiedz

9

Cóż, jak o korzystaniu z lunetą zmienne typu wybierz wewnętrzny komponent:

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

import Data.Dynamic 
import Data.Typeable 

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

działa dla mnie:

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

ciekawy design.

8

W notatce stycznej do rozwiązania Dona zauważ, że kod rzadko wymaga ScopedTypeVariables. Po prostu sprawia, że ​​rozwiązanie jest czystsze (ale mniej przenośne). Rozwiązanie nie jest objęty zakresem typów:

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

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

getTypeRep :: forall t a. Typeable a => t a -> TypeRep 
getTypeRep = typeOf . helper 
Powiązane problemy