Obecnie jestem w Chapter 8 z Learn you a Haskell i dotarłem do sekcji na typeclass Functor
. W tej sekcji autor podaje przykłady, jak różne typy mogą być tworzone wystąpienia klasy (np. Maybe
, niestandardowy Tree
itp.) Widząc to, postanowiłem (dla zabawy i praktyki) spróbuj wdrożyć instancję dla typu Data.Set
; w tym wszystkim oczywiście ignorując Data.Set.map
.W jaki sposób można wykonać wiązanie klasy w instancji klasy, która wymaga konstruktora typu, a nie konkretnego typu?
Sam rzeczywisty przypadek jest dość prosta, a ja napisałem to jako:
instance Functor Set.Set where
fmap f empty = Set.empty
fmap f s = Set.fromList $ map f (Set.elems s)
Ale ponieważ zdarza mi się korzystać z funkcji fromList
Daje to w ograniczeniu klasy wzywając do rodzajów stosowanych w Set
być Ord
, jak to wytłumaczyć błąd kompilatora:
Error occurred
ERROR line 4 - Cannot justify constraints in instance member binding
*** Expression : fmap
*** Type : Functor Set => (a -> b) -> Set a -> Set b
*** Given context : Functor Set
*** Constraints : Ord b
Patrz: Live Example
I tri ed nałożenie ograniczenia na instancję lub dodanie sygnatury typu do fmap
, ale żadna z nich nie powiodła się (obie były również błędami kompilatora).
Jak w takiej sytuacji można spełnić i zaspokoić przymus? Czy jest jakiś możliwy sposób?
Z góry dziękuję! :)
Jeden problem z ograniczonych klas funktorów jest to, że tracimy dużo energii. Szczególnie w przypadku funktorów aplikacyjnych często chcemy umieszczać w nich funkcje. Jednak w wielu przypadkach niemożliwe jest podanie ogólnych wystąpień klas, które są zainteresowane funkcjami. – hammar