Rozumiem, dlaczego chcesz to zrobić, ale niestety, może to bądź tylko złudzeniem, że zajęcia Haskella wydają się być "otwarte" w sposób, w jaki mówisz. Wiele osób uważa, że możliwość wykonania tego jest błędem w specyfikacji Haskell, z powodów, które wyjaśnię poniżej. W każdym razie, jeśli naprawdę nie jest właściwe dla instancji, która ma być zadeklarowana w module, w którym klasa jest zadeklarowana lub w module, w którym zadeklarowano typ, prawdopodobnie jest to znak, że powinieneś używać newtype
lub jakiegoś innego otoki wokół swojego typu.
Powody, dla których należy unikać wystąpienia sierocy, są znacznie głębsze niż wygoda kompilatora. Ten temat jest dość kontrowersyjny, jak widać z innych odpowiedzi. Aby zrównoważyć dyskusję, zamierzam wyjaśnić punkt widzenia, że nigdy nie należy pisać sierocych instancji, co moim zdaniem jest większościową opinią doświadczonych Haskellerów. Moja własna opinia jest gdzieś pośrodku, co wyjaśnię na końcu.
Problem wynika z faktu, że gdy istnieje więcej niż jedna deklaracja wystąpienia dla tej samej klasy i typu, nie ma mechanizmu w standardowym Haskell, który określałby, którego użyć. Zamiast tego program jest odrzucany przez kompilator.
Najprostszym efektem tego jest to, że możesz mieć doskonale działający program, który nagle przestałby się kompilować z powodu zmiany, którą ktoś inny popełnia w pewnej odległej zależności od twojego modułu.
Co gorsza, program roboczy może zacząć się od awarii w środowisku wykonawczym z powodu odległej zmiany. Możliwe, że używasz pewnej metody, która pochodzi z deklaracji konkretnej instancji i może zostać bezgłośnie zastąpiona przez inną instancję, która jest na tyle inna, aby spowodować, że twój program zacznie się w niewytłumaczalny sposób ulegać awarii.
Osoby, które chcą zagwarantować, że problemy te nigdy się z nimi nie spotkają, muszą przestrzegać zasady, że jeśli ktokolwiek i gdziekolwiek kiedykolwiek zadeklarował instancję danej klasy dla określonego typu, żadna inna instancja nie może być ponownie zadeklarowana w każdym programie napisanym przez każdego. Oczywiście istnieje obejście problemu z użyciem newtype
do zadeklarowania nowej instancji, ale zawsze jest to co najmniej drobna niedogodność, a czasem poważna. W tym sensie ci, którzy świadomie piszą sierocą instancje, są raczej niegrzeczni.
Co należy zrobić w związku z tym problemem? Obóz anty-osierocony mówi, że ostrzeżenie GHC jest błędem, musi to być błąd, który odrzuca każdą próbę zadeklarowania instancji osieroconej. W międzyczasie musimy ćwiczyć samodyscyplinę i unikać jej za wszelką cenę.
Jak widzieliście, są tacy, którzy nie martwią się tymi potencjalnymi problemami. Właściwie zachęcają do korzystania z instancji osieroconych jako narzędzia do rozdzielania obaw, jak sugerujesz, i mówią, że należy po prostu upewnić się, że w każdym przypadku nie ma problemu. Byłem wystarczająco niedogodny z powodu sierocych instancji innych ludzi, aby być przekonanym, że ta postawa jest zbyt nieprzyzwoita.
Myślę, że właściwym rozwiązaniem byłoby dodanie rozszerzenia do mechanizmu importu Haskell, który kontrolowałby import wystąpień. Nie rozwiązałoby to całkowicie problemów, ale pomogłoby w ochronie naszych programów przed uszkodzeniami z istniejących już na świecie instancji sierocych. A potem, z czasem, mogę przekonać się, że w pewnych ograniczonych przypadkach być może sierota nie jest taka zła. (I ta pokusa jest powodem, dla którego niektórzy w obozie przeciw sierocym instancjom sprzeciwiają się mojej propozycji.)
Mój wniosek z tego wszystkiego jest taki, że przynajmniej na razie zdecydowanie zaleciłbym unikanie ogłaszanie jakichkolwiek osieroconych instancji, bycie rozważnym dla innych, jeśli nie z innego powodu. Użyj newtype
.
Dyskusja w odpowiedziach i komentarzach pokazuje, że istnieje duża różnica między definiowaniem instancji sierocych w pliku wykonywalnym *, tak jak to robisz, w bibliotece *, która jest narażona na inne. [To niezwykle popularne pytanie] (http://stackoverflow.com/q/26770247/) ilustruje, jak mylące instancje mogą być dla użytkowników końcowych biblioteki, która je definiuje. –