2011-09-23 11 views
8

Jestem tylko ciekaw, dlaczego muszę to napisać,wyjaśnienie dla "nielegalne typu synonim rodziny"

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl γ where 
    var = varhz 

zamiast tego

instance (HzMonad , Data.Suitable.Suitable α) => VarDecl (ExprTyp α) where 
    var = varhz 

-- error 
Hz2/Language.hs:114:53: 
    Illegal type synonym family application in instance: ExprTyp α 
    In the instance declaration for `VarDecl (ExprTyp α)' 

gdzie

varhz :: 
    (HzMonad , Data.Suitable.Suitable α) => 
    String -> ExprTyp α -> (ExprTyp α) 

Co jest ty tak czy inaczej tylda? Dziękuję bardzo.

+3

Nie mam energii (dziś wieczorem), aby napisać kompletną odpowiedź, ale krótka odpowiedź brzmi, że jest to jeszcze jeden przykład głęboko zakorzenionych założeń na temat poziomu rzeczy, które są iniekcyjne, okazując się fałszywe, gdy typ rodziny są dodawane do miksu. Tilda jest asercją równości typu. –

+0

Ah, teraz rozumiem, żadnych problemów. Dziękuję za notatkę. Jak obejść to jest inna historia, którą wciąż staram się rozgryźć. – gatoatigrado

Odpowiedz

2

Myślę, że problem polega na tym, że wszystko po prawej stronie => musi być konstruktorem typu lub zmienną typu. ExprTyp może odnosić się do konstruktorów typu multiple differet. Zastąpienie tego ograniczeniem równości rzeczywiście będzie działało, ale wynikowa instancja będzie efektywnie bezużyteczna, ponieważ kompilator nie będzie w stanie wydedukować niczego o γ, ponieważ jest to ExprTyp - ExprTyp może być aliasowany do czegokolwiek.

W mojej sytuacji - próbuję napisać monadę DSL - rozwiązaniem jest zawijanie wszystkich zastosowań skojarzonego typu w konstruktorze typów new. Na przykład, jeśli zaczniemy,

class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprTyp m a -> m() 

następnie owijając spowoduje

newtype ExprT a = ExprT a 
class MyDSL m a where 
    type ExprTyp m :: * -> * 
    printE :: ExprT (ExprTyp m a) -> m() 

Następnie, dla przykładu, deklaracje zmiennych (pisałem kod tupled deklaracji zmiennych) mogłaby być,

instance (HzMonad , Data.Suitable.Suitable α, γ ~ ExprTyp α) => VarDecl (ExprT γ) 
instance (Monad , VarDecl α, VarDecl β) => VarDecl (α, β) 

proszę napisać komentarz, jeśli coś jest niejasne.