2012-10-29 6 views

Odpowiedz

22

TypeSynonymInstances jest całkowicie bezpieczny. Ponieważ coś potencjalnie fantazyjny jak częściowo stosowanymi synonimami typu jest niedozwolone, to ma dokładnie taki sam efekt jak wpisanie się po stronie prawicy typu synonim w głowie instancji, tj

type Foo a = ([a], [a]) 
instance Bar (Foo a) 

jest taka sama jak

instance Bar ([a], [a]) 

Należy jednak pamiętać, że obie instancje wymagają FlexibleInstances, ponieważ zawierają konstruktory typów zagnieżdżonych, a także zmienne typu powtarzalnego. Zazwyczaj dzieje się tak po rozszerzeniu synonimów typu.

Myślę, że to może być powód, dla którego są one domyślnie zabronione.

Jednak jest również całkowicie bezpiecznym przedłużeniem. Najgorsze może zrobić to spowodować błąd kompilacji, jeśli starają się określić nakładających się przypadki takie jak

instance Xyzzy String 
instance Xyzzy [a] 

Jak, dlaczego FlexibleInstances nie jest dostępna domyślnie, mogę się tylko domyślać, że to uproszczenie języka. Standardowe reguły dla nagłówków instancji zapewniają, że jedyne możliwe definicje instancji sposobu mogą się pokrywać, jeśli konstruktory typów w głowicach instancji są identyczne, a sprawdzanie pokrywania się jest nieco trudniejsze niż w przypadku FlexibleInstances.

14

Jak rozumiem, jest to coś w rodzaju ograniczenia monomorfizmu - nie ma nic złego w pozbyciu się tego, ale otwiera cię na zachowanie, którego możesz nie oczekiwać. Tak jak monomorfizm, ograniczenie nie niszczy niczego - wszystkie te typy są nadal ważne - to również powinno być całkowicie bezpieczne: istnieją ograniczenia co do synonimów typu, które i tak nie pozwalają im na nic bardziej przyjemnego niż zwykłe skrócenie nazwy (, np., ty nigdy nie mogą ich częściowo zastosować, więc nie otrzymujemy lambd z poziomu typu), więc zawsze można je zastąpić prawą stroną ich definicji. W związku z tym, ponieważ prawe strony tych definicji mogą być sprawdzane jako nagłówki instancji (lub zawierają dodatkowe synonimy do rozwinięcia), nic nie powinno być niebezpieczne.

Z drugiej strony, podobnie jak wyłączenie ograniczenia monomorfizmu otwierają się potencjalnie dziwne charakterystyki wydajności, włączenie instancji synonimów typu otwiera się na błędy klasy potencjalnie nieparzystej. Warto więc włączyć -XTypeSynonymInstances i spróbuj pisząc wystąpienie z synonim typu:

Prelude> :set -XTypeSynonymInstances 
Prelude> instance Num String where (+) = (++) 

<interactive>:3:10: 
    Illegal instance declaration for `Num String' 
     (All instance types must be of the form (T a1 ... an) 
     where a1 ... an are *distinct type variables*, 
     and each type variable appears at most once in the instance head. 
     Use -XFlexibleInstances if you want to disable this.) 
    In the instance declaration for `Num String' 

String wygląda jak zwykły starego typu, więc może to być zaskakujące na pierwszy; ale tak naprawdę jest to [Char], więc ta instancja jest nieważna zgodnie ze ścisłymi regułami Haskell 2010.Jeśli odpoczywamy tych zasad obracając kolej na -XFlexibleInstances (który, nawiasem mówiąc, implies -XTypeSynonymInstances), ten przykład działa teraz:

Prelude> :set -XFlexibleInstances 
Prelude> instance Num String where (+) = (++) 
... errors about undefined methods ... 
Prelude> "a" + "b" 
"ab" 

Ale sytuacja staje się brzydka szybko:

Prelude> instance Eq String where 
Prelude> "a" == "b" 

<interactive>:8:5: 
    Overlapping instances for Eq [Char] 
     arising from a use of `==' 
    Matching instances: 
     instance Eq a => Eq [a] -- Defined in `GHC.Classes' 
     instance Eq String -- Defined at <interactive>:7:10 
    In the expression: "a" == "b" 
    In an equation for `it': it = "a" == "b" 

Ponownie, choć String wygląda odrębny typ, mamy już instancję dla [a], a więc nakłada się z nią. (I w rzeczywistości jest to prawdopodobnie powodem, dla którego -XFlexibleInstances nie jest domyślnie włączony). Włączenie -XOverlappingInstances to a much dodgier idea niż włączenie -XFlexibleInstances.

5

Kiedyś było dozwolone, ale próbując sprawić, by Haskell był mniej pełen niespodzianek dla początkujących, został zbanowany.

Powiązane problemy