Jeszcze bardziej uogólnione wyprowadzanie nowego typu
Nowe typy są często używane do zmiany zachowania niektórych typów, gdy są używane w pewnych kontekstach klasowych. Na przykład można użyćData.Monoid.All
wrapper do zmiany zachowaniaBool
gdy jest używany jakoMonoid
.
Obecnie piszę takie opakowanie typu newtype, które ma zastosowanie do wielu różnych typów. Opakowanie ma zmienić zachowanie jednej konkretnej instancji klasy. Może to wyglądać tak:
newtype Wrapper a = Wrapper a
instance Special a => Special (Wrapper a) where
-- ...
Jednak dodanie tego opakowania często zmienia użyteczność opakowanego typu. Na przykład, jeśli wcześniej byłem w stanie użyć tej funkcjimconcat :: Monoid a => [a] -> a
, Nie mogę teraz użyć go do listy zawiniętych wartości.
Mogę oczywiście użyć-XGeneralizedNewtypeDeriving
inewtype Wrapper a = Wrapper a deriving (Monoid)
. Jednak rozwiązuje to tylko problemMonoid
i żadna inna klasa, podczas gdy ja będę miał do czynienia z otwartym światem pełnym różnych klas i samodzielnym generowanym sierocym uogólnionym nowym typem, nie jest tak naprawdę praktyczną opcją. Idealnie chciałbym napisaćderiving hiding (Special)
(uzyskując każdą klasę z wyjątkiemSpecial
), ale to nie jest ważne Haskell, oczywiście.
Czy jest jakiś sposób, aby to zrobić, czy jestem po prostu przykręcony i muszę dodać żądanie funkcji GHC?