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ą:
- Dlaczego operatorzy Infix i prefiks wykazują różne zachowanie?
- Dlaczego
~
wiąże się tak mocno? - 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 ~
.)
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
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
Mam bilet [GHC] (https://ghc.haskell.org/trac/ghc/ticket/10056) teraz – crockeea