2014-09-17 16 views
5

Ich versuche, eine Typeable Instanz für Tupped Constraints abzuleiten. Siehe den folgenden Code:Typierbare Instanz für Constraint tupling

{-# LANGUAGE ConstraintKinds, GADTs #-} 
{-# LANGUAGE DataKinds, PolyKinds, AutoDeriveTypeable #-} 
{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-} 

import Data.Proxy 
import Data.Typeable 

data Foo (p :: (*, *)) 

data Dict ctx where 
    Dict :: ctx => Dict ctx 
    deriving (Typeable) 

deriving instance Typeable '(,) 
deriving instance Typeable Typeable 
deriving instance Typeable Show 

works :: IO() 
works = print (typeRep (Proxy :: Proxy (Foo '(Bool, Char)))) 

alsoWorks :: IO() 
alsoWorks = print (typeRep (Dict :: Dict (Show Bool))) 

fails :: IO() 
fails = print (typeRep (Dict :: Dict (Show Bool, Typeable Bool))) 

main :: IO() 
main = works >> alsoWorks >> fails 

Wenn Sie diese kompilieren mit -fprint-explicit-kinds, wird der folgende Fehler gegeben:

No instance for (Typeable 
        (Constraint -> Constraint -> Constraint) (,)) 

Gibt es eine Möglichkeit, eine solche Instanz ableiten? Alles, was ich versuche, weigert sich, aus dem Konstruktor ★ -> ★ -> ★ zu disambiguieren.

Antwort

5

GHC derzeit nicht machen eine Typeable eine Instanz oder eine andere Instanz, für (,) :: Constraint -> Constraint -> Constraint. Der Typkonstruktor (,) hat nur die Art * -> * -> *. There is no type constructor for products of the kind Constraint -> Constraint -> Constraint. Der Konstruktor (,) ist überladen, um sowohl Tupel als auch Produkte von Constraints zu konstruieren, hat jedoch keinen entsprechenden Typenkonstruktor, wenn er zur Herstellung eines Produkts von Constraints verwendet wird.

Wenn wir einen Typkonstruktor für Produkte von Constraint s haben, sollten wir in der Lage sein, eine Instanz wie folgt zu definieren. Dafür werden wir so tun (,) ist auch ein Typ Konstruktor mit Art . Um eine Instanz zu definieren für sie, wir KindSignatures verwenden würde und importieren GHC.Exts.Constraint der Lage sein, über die Art der Zwänge zu sprechen ausdrücklich

{-# LANGUAGE ConstraintKinds #-} 
{-# LANGUAGE StandaloneDeriving #-} 
{-# LANGUAGE DeriveDataTypeable #-} 
{-# LANGUAGE KindSignatures #-} 

import GHC.Exts (Constraint) 
import Data.Typeable 

deriving instance Typeable ((,) :: Constraint -> Constraint -> Constraint) 

Wenn wir dies tun, jetzt, es ergibt sich folgende Fehler, aufgrund der Art des (,) Typ Konstruktors.

The signature specified kind `Constraint 
           -> Constraint -> Constraint', 
    but `(,)' has kind `* -> * -> *' 
In the stand-alone deriving instance for 
    `Typeable ((,) :: Constraint -> Constraint -> Constraint)' 

Das constraints Paket funktioniert auch mit Produkten von Einschränkungen und umfasst the following note.

aufgrund des Hack für die Art von (,) in der aktuellen Version von GHC können wir nicht wirklich Instanzen machen für (,) :: Constraint -> Constraint -> Constraint

Ich nehme an den Hack Edward Kmett sich bezieht ist die Überlastung der (,) Konstruktor für Constraint s ohne entsprechenden Typkonstruktor.

+0

Die Fehlermeldung 'No instance for (Typierbar (Constraint -> Constraint -> Constraint) (,))' scheint zu implizieren, dass ein Typkonstruktor * intern * irgendwie existiert. Wenn es nur einen Namen hätte, könnten wir ... –

2

Es scheint, dass dies derzeit nicht möglich ist. Es gibt einen aufschlussreichen Kommentar im latest version von constraint:

aufgrund des Hack für die Art von (,) in der aktuellen Version von GHC können wir nicht wirklich Instanzen für (,) machen :: Constraint -> Constraint -> Constraint

+1

Ihr Kommentar über kmett es schädlich für die Gemeinschaft. Nicht im geringsten seine Fähigkeiten zu verachten, aber lass uns keine Götter haben. – luqui

+0

@luqui Sehr gut, ersetzt durch etwas hoffentlich harmlos. –