Non credo di capire le classi di tipi. Ho letto da qualche parte che pensare alle classi di tipi come "interfacce" (da OO) che un tipo implementa è sbagliato e fuorviante. Il problema è che sto avendo problemi a vederli come qualcosa di diverso e come ciò sia sbagliato.
Ad esempio, se ho una classe di tipo (nella sintassi di Haskell)
class Functor f where
fmap :: (a -> b) -> f a -> f b
In che modo differisce dall'interfaccia [1] (nella sintassi Java)
interface Functor<A> {
<B> Functor<B> fmap(Function<B, A> fn)
}
interface Function<Return, Argument> {
Return apply(Argument arg);
}
Una possibile differenza che mi viene in mente è che l'implementazione della classe di tipo utilizzata in una determinata chiamata non è specificata ma piuttosto determinata dall'ambiente, ad esempio esaminando i moduli disponibili per un'implementazione per questo tipo. Quello sembra essere un artefatto di implementazione che potrebbe essere affrontato in un linguaggio OO; come il compilatore (o il runtime) potrebbe cercare un wrapper / extender / monkey-patcher che espone l'interfaccia necessaria sul tipo.
Cosa mi sto perdendo?
[1] Nota che l' f a
argomento è stato rimosso dal fmap
momento che dato che è un linguaggio OO, avresti chiamato questo metodo su un oggetto. Questa interfaccia presuppone che l' f a
argomento sia stato risolto.