2010-10-30 12 views
9

Supponiamo di definire un GADT per il confronto di modelli:confronto runtime dei tipi per il sollevamento di strutture dati polimorfi in GADTs

data EQT a b where 
    Witness :: EQT a a 

È quindi possibile dichiarare una funzione EQT con la seguente firma di tipo:

eqt :: (Typeable a, Typeable b) => a -> b -> Maybe (EQT a b) 

... tale che EQT xy restituisce Proprio testimone se typeOf x == t ypeOf y --- o altrimenti a Niente?

La funzione eqt consentirebbe di sollevare strutture di dati polimorfiche ordinarie in GADT.

risposta

11

Sì, lo è. Ecco un modo:

Primo, il tipo di uguaglianza di tipo.

Si noti che può essere reso un'istanza di Typeable. Questa è la chiave. Ora ho solo bisogno di mettere le mani sul Refl di cui ho bisogno, come questo.

refl :: a -> EQ a a 
refl _ = Refl 

E ora posso cercare di trasformare (Refi :: Eq a a) in qualcosa di tipo (Eq un b) utilizzando operatore di cast di Data.Typeable. Funzionerà solo quando a e b sono uguali!

eq :: (Typeable a, Typeable b) => a -> b -> Maybe (EQ a b) 
eq a _ = cast (refl a) 

Il duro lavoro è già stato fatto.

Altre variazioni su questo tema sono disponibili nella libreria Data.Witness, ma l'operatore di cast Data.Typeable è tutto ciò che serve per questo lavoro. È imbrogliare , naturalmente, ma imbrogliare in modo sicuro impacchettato.

+0

Questo è pulito! Grazie. –

+0

Compresso sicuro fino a quando nessuno ha effettuato un'istanza 'Data.Typeable' errata su qualcosa. ('derivante Typeable' è sempre sicuro.) –

+0

Si noti che in questi giorni' eq' è disponibile nel modulo 'Data.Typeable' come [' eqT'] (https://hackage.haskell.org/package/base-4.9 .0.0/docs/Data-Typeable.html # v: EQT) –

Problemi correlati