Sono attualmente in Chapter 8 di Learn you a Haskell e ho raggiunto la sezione sulla classe Functor
. In questa sezione l'autore fornisce esempi di come tipi diversi possono essere realizzati istanze della classe (ad esempio, un tipo personalizzato Tree
, ecc.) Vedendo questo, ho deciso di (per divertimento e pratica) provare ad implementare un'istanza per il tipo Data.Set
; in tutto questo ignorando lo Data.Set.map
, ovviamente.Come si può soddisfare un vincolo di classe in un'istanza di una classe che richiede un costruttore di tipi piuttosto che un tipo concreto?
L'istanza vera e propria è abbastanza straight-forward, e ho scritto come:
instance Functor Set.Set where
fmap f empty = Set.empty
fmap f s = Set.fromList $ map f (Set.elems s)
Ma, dal momento che mi capita di usare la funzione fromList
questo porta a un vincolo di classe chiamando per i tipi utilizzati nel Set
di essere Ord
, come si spiega con un errore di compilazione:
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
See: Live Example
I Tri Ed inserendo un vincolo sull'istanza o aggiungendo una firma di tipo a fmap
, ma nessuno dei due ha avuto esito positivo (entrambi erano errori del compilatore.)
Data una situazione come questa, come può essere soddisfatto e soddisfatto un vincolo? C'è qualche modo possibile?
Grazie in anticipo! :)
un problema con le classi functor vincolata è che si perde un sacco di potenza. Specialmente con i funtori applicativi, spesso desideriamo inserirvi delle funzioni. Tuttavia, in molti casi è impossibile fornire istanze generali delle classi a cui siamo interessati per le funzioni. – hammar