11 Stimmen

Haskell -- liefert TypeRep aus konkreter Typinstanz

Ich möchte eine Funktion mit dieser Typsignatur schreiben:

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

wobei TypeRep die Typdarstellung für a , nicht für t a . Das heißt, der Compiler sollte automatisch die korrekte Typdarstellung an allen Aufrufstellen [nach getTypeRep ], die über konkrete Typen für a .

Um den Kontext zu verdeutlichen, möchte ich einen Datentyp "Dynamischer Typ" erstellen, der sich zwar den Typ der obersten Ebene merkt, nicht aber dessen Parameter. Zum Beispiel möchte ich aus MyClass a en Dynamische MyClass und die obige Funktion wird verwendet, um Instanzen von Dynamische MyClass die eine Darstellung des Typparameters speichern a .

9voto

Don Stewart Punkte 136046

Wie wäre es, wenn Sie die innere Komponente mit Hilfe von scoped type variables auswählen?

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

import Data.Dynamic
import Data.Typeable

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

Funktioniert bei mir:

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

Interessantes Design.

8voto

Thomas M. DuBuisson Punkte 63725

Eine Randbemerkung zu Dons Lösung ist, dass der Code selten erfordern ScopedTypeVariables. Es macht die Lösung nur sauberer (aber weniger portabel). Die Lösung ohne scoped types ist:

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

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

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

0voto

glguy Punkte 1090

Diese Funktion existiert (jetzt) in Data.Typeable typeRep

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X