2011-11-13 10 views
6

W Associated Type Synonyms (Chakravarty, Keller, Jones) papier wydaje się wskazywać, że następujące jest prawidłowy:Czy możliwe jest posiadanie skojarzonego synonimu ze zmiennymi niewymienionymi w klasie typu?

class C a where 
    type S a (k :: * -> *) :: * 

Jednak gdy próbuję i uruchomić to pojawia się błąd kompilatora (z -XTypeFamilies):

Not in scope: type variable `k' 

Czy brakuje mi czegoś, czy też faktyczna realizacja w GHC nie jest taka sama, jak wspomniano w artykule?

+0

Znalazłem http://hackage.haskell.org/trac/ghc/ticket/3714, który dla mnie brzmi tak, jakby tego nie można było zrobić. Jeśli to prawda, odpowiedz na to. – ocharles

Odpowiedz

4

Jak już dowiedzieliśmy, this is not possible in GHC:

Dokładnie jak w przypadku skojarzonego deklaracji danych wymienieni parametry typu muszą być permutacją podzbioru parametrów klasy. Przykłady

class C a b c where { type T c a :: * } -- OK 
class D a where { type T a x :: * }  -- No: x is not a class parameter 
class D a where { type T a :: * -> * } -- OK 

Bilet Państwo mowa faktycznie wyjaśnia przyczyny nie jest w stanie określić coś jak S. Działa, jeśli robisz to tak:

class C a where 
    type S a :: (* -> *) -> * 
data TupK a k = TupK (a, k a) 
instance C [a] where 
    type S [a] = TupK a 

Jednak teraz utknąłeś z nowym typem danych. Używanie synonimów typu nie zadziała ("Synonim typu" TupK "powinien mieć 2 argumenty"), a dodanie kolejnych parametrów do S nie pomoże ("Liczba parametrów musi być zgodna z deklaracją rodziny, oczekiwana 1"), zgodnie z dokumentacją bilet.

+0

Bummer, ale dzięki za szczegółową odpowiedź! – ocharles

+1

@ charles Dodałbym, że nie * masz * używać * skojarzonego * typu. Można doskonale zrobić coś takiego jak "typ rodziny S a (k :: * -> *); klasa C a gdzie foo :: S a [] -> Int'. Główną zaletą skojarzonych typów jest to, że ułatwia kompilatorowi przekazywanie dobrych komunikatów o błędach (i wygodniejszej składni deklaracji typu instancji). –

+0

Tak, na razie rozdzieliłem 2, ale miło było je sparować – ocharles

1

Nie, ale można zrobić mniej wydajne:

class C a where 
    type S a :: (k :: * -> *) -> * 

... które mogłyby służyć temu samemu celowi, jeżeli nie potrzebują dodatkowego zasilania.

Powiązane problemy