Я не думаю, що я розумію типи класів. Я десь читав, що мислення про типові класи як "інтерфейси" (від OO), що тип реалізує, є неправильним та оманливим. Проблема полягає в тому, що у мене виникають проблеми бачити їх як щось інше, і як це неправильно.
Наприклад, якщо у мене клас типу (у синтаксисі Haskell)
class Functor f where
fmap :: (a -> b) -> f a -> f b
Чим це відрізняється від інтерфейсу [1] (у синтаксисі Java)
interface Functor<A> {
<B> Functor<B> fmap(Function<B, A> fn)
}
interface Function<Return, Argument> {
Return apply(Argument arg);
}
Я можу подумати про те, що реалізація класу типів, яка використовується при певному виклику, не задається, а визначається з оточення - скажімо, вивчаючи доступні модулі для реалізації для цього типу. Це здається артефактом впровадження, який можна вирішити мовою ОО; як-от компілятор (або час виконання) міг би шукати обгортку / розширювач / monkey-patcher, яка виставляє необхідний інтерфейс для типу.
Що я пропускаю?
[1] Зверніть увагу, що f a
аргумент вилучено з того fmap
моменту, як це є мовою ОО, ви будете викликати цей метод на об'єкті. Цей інтерфейс передбачає, що f a
аргумент виправлено.