Nie sądzę, że rozumiem klasy typów. Czytałem gdzieś, że myślenie o klasach typów jako „interfejsach” (od OO), które implementuje typ, jest błędne i wprowadza w błąd. Problem polega na tym, że mam problem z postrzeganiem ich jako czegoś innego i jak to jest złe.
Na przykład, jeśli mam klasę typu (w składni Haskell)
class Functor f where
fmap :: (a -> b) -> f a -> f b
Czym różni się to od interfejsu [1] (w składni Java)
interface Functor<A> {
<B> Functor<B> fmap(Function<B, A> fn)
}
interface Function<Return, Argument> {
Return apply(Argument arg);
}
Jedną z możliwych różnic, o których mogę pomyśleć, jest to, że implementacja klasy typu zastosowana przy pewnym wywołaniu nie jest określona, ale raczej określona na podstawie środowiska - powiedzmy, sprawdzając dostępne moduły dla implementacji dla tego typu. Wydaje się, że jest to artefakt implementacyjny, który można rozwiązać w języku OO; tak jak kompilator (lub środowisko wykonawcze) może skanować w poszukiwaniu wrappera / przedłużacza / monkey-patchera, który udostępnia wymagany interfejs dla danego typu.
czego mi brakuje?
[1] Uwaga: f a
argument został usunięty, fmap
ponieważ ponieważ jest to język OO, wywołałbyś tę metodę na obiekcie. Ten interfejs zakłada, że f a
argument został naprawiony.