2013-04-21 17 views
6

Powiedz, że mam następujący (błędny) kod.Haskell Błąd z niepoprawnym kodem?

data A a b where 
    APure :: (A a b) 
    AApply :: A (A b c) c 

test :: (A a b) -> a -> b 
test (APure) a = a 
test AApply a = undefined 

GHC wtedy dać mi ten błąd:

Couldn't match type `b' with `A b1 b' 
    `b' is a rigid type variable bound by 
     the type signature for test :: A a b -> a -> b 
Inaccessible code in 
    a pattern with constructor 
    AApply :: forall c b. A (A b c) c, 
    in an equation for `test' 
In the pattern: AApply 
In an equation for `test': test AApply a = undefined 

nie jest to komunikat o błędzie całkowicie błędne? Błąd nie ma nic wspólnego z AApply.

+1

W jaki sposób "AApply" powinien mieć ogólny typ "A a b", jeśli zadeklarowałeś go jako "A (A b c) c"? To tak, jakbyś definiował 'concat ':: [a] -> [b]' jako 'concat' = concat': jak Haskell zamierza zunifikować' a' "down" do '[b]' ?. – leftaroundabout

+1

Tak, to nieintuicyjne. Być może powinieneś [zgłosić błąd] (http://hackage.haskell.org/trac/ghc/newticket?type=bug). –

+0

@leftaroundabout Nie rozumiem, co masz na myśli, ale ta sprawa jest poprawna. Czytaj na temat wzorcowania z GADT. – nulvinge

Odpowiedz

4

Isn't this error message completely wrong? The error has nothing to do with AApply .

Nie całkowicie. Jest to prawdopodobnie błąd, który powoduje pojawienie się tego komunikatu o błędzie, ale nie jest całkowicie nieoparty.

Spójrz na całość razem, patrząc na kawałki.

test (APure) a = a 

mówi mamy funkcję

test :: A a b -> r -> r 

umieścić, że wraz z podpisem

test :: (A a b) -> a -> b 

i ujednolicenia, ignorując typu błędu z pierwszego równania, typ jest dopracowane do

test :: A r r -> r -> r 

Następnie spojrzeć na równaniu

test AApply a = undefined 

i zobaczyć, jak to jest niedostępne w ramach wyrafinowanego rodzaju, ponieważ

AApply :: A (A b c) c 

wiązałoby

c ~ A b c 

jeśli AApply był ważny pierwszy argument.

+0

Podejrzewałem, że coś takiego się stało. Dlaczego łączy się z 'A r r -> r -> r'? W jaki sposób typ może zmienić się w coś innego, gdy określony jest typ funkcji? – nulvinge

+0

W przypadku GADT uzyskujesz wyrafinowanie typu. Myślę, że to, co dzieje się tutaj, to błąd w sprawdzaniu poprawności (i 6.12.3, otrzymujesz nieprzyjemne "Nie można dopasować oczekiwanego typu" b "do wywnioskowanego typu' a''' dla pierwszego równania; 7.0, 7.2 i 7.4 dają tylko błąd dla drugiego równania, 7.6 oba) - resp. producent komunikatów o błędach, udoskonalenie poszło nie tak. Powinien zatrzymać się na błędzie w pierwszym równaniu. Ale kiedy to się powtórzyło, działało to z niespójnymi hipotezami, więc nie jest to zbyt zaskakujące, że kończy się głupim rezultatem. –

+0

Och, więc jest to błąd, który został naprawiony (ale moja wersja GHC jest stara). Dzięki! – nulvinge