2015-01-31 9 views
18

Poniższy fragment kompiluje:Jaki jest priorytet ~ i dlaczego?

{-# LANGUAGE TypeFamilies #-} 
type family Foo a b 

f :: (Foo a b ~ Int) => a -> b -> b 
f = error "" 

ale infix typu operatorzy wydają się zachowywać inaczej:

{-# LANGUAGE TypeFamilies #-} 
type family a \\ b 

f :: (a \\ b ~ Int) => a -> b -> b 
f = error "" 

GHC narzeka, że ​​drugi argument \\ powinien mieć miłą *, ale b ~ Int ma rodzaj Constraint . Oczywiście można to naprawić za pomocą paren, ale zastanawiam się, czy istnieje inny sposób.

Próbowałem ustawienie pierwszeństwo mojego operatora z deklaracją stałość infixl 9 \\, ale to nie rozwiązuje problemu, wskazując, że pierwszeństwo ~ jest at least 9 (jeśli mam interpretowania że poprawnie). Próbowałem użyć sztuczki z this answer, aby GHCi powiedział mi, że mam pierwszeństwo przed ~, ale to nie zadziałało.

Technicznie rzecz biorąc, ~ prawdopodobnie nie jest operatorem typu, to bardziej leksykalnym konstrukcji podobnej do ,, ale pytania nadal stoją:

  1. Dlaczego operatorzy Infix i prefiks wykazują różne zachowanie?
  2. Dlaczego ~ wiąże się tak mocno?
  3. Czy jest coś, co mogę zrobić, aby moi operatorzy jeszcze bardziej się związali?

(Uwaga: This question prosi o pierwszeństwo funkcji typu, ale nie mówi nic o ~.)

+0

Kolejną dziwną rzeczą jest to, że jeśli pytam GHCi ': k (~)', to mówi mi '(~) :: K -> K -> Constraint', ale jeśli zapytaj ': i (~)', mówi mi 'błąd analizy na wejściu '~''. Coś wydaje się być bardzo dziwne, jak parser obsługuje '~'. – dfeuer

+0

Nie jestem pewien, jaka jest tego przyczyna - '~' ma pewne szczególne zachowania, ponieważ jest wbudowaną funkcją typu i może powinna być spójna z innymi rzeczami. Ale jeśli ci to przeszkadza, możesz zrobić coś w stylu 'type (==) = (~); infixr 0 == ', który byłby nawet bardziej spójny pod względem składni między terminem a typem. – user2407038

+0

Mam bilet [GHC] (https://ghc.haskell.org/trac/ghc/ticket/10056) teraz – crockeea

Odpowiedz

1

~ nie jest operatorem, jest to słowo kluczowe, jak module lub case, więc Myślę, że możesz zmienić pierwszeństwo używając nawiasów.

Zobacz więcej tutaj: https://wiki.haskell.org/Keywords#.7E

+0

To oczywiście nie jest cała historia. Tak, '~' we wzorcu jest składnią, ale w innych kontekstach jest operatorem typu. – dfeuer

+1

Wygląda to na operatora typu, ponieważ można uzyskać jego rodzaj, ale czy to możliwe, że po prostu działa tak jak jeden? – lightandlight

+0

Nie jestem wystarczająco zaawansowany, aby przeczesać źródło dla implementacji, ale podejrzewam, że tak. – lightandlight