Я не думаю, что понимаю классы типов. Я где-то читал, что думать о классах типов как о «интерфейсах» (из ОО), которые реализует тип, неправильно и вводит в заблуждение. Проблема в том, что я испытываю проблемы, видя их как нечто иное, и как это неправильно.
Например, если у меня есть класс типов (в синтаксисе 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);
}
Одно возможное различие, о котором я могу подумать, состоит в том, что реализация класса типов, используемая при определенном вызове, не указывается, а скорее определяется из среды - скажем, исследуя доступные модули для реализации для этого типа. Похоже, это артефакт реализации, который может быть решен на языке ОО; подобно тому, как компилятор (или среда выполнения) может сканировать оболочку / extender / monkey-patcher, который предоставляет необходимый интерфейс для типа.
Чего мне не хватает?
[1] Обратите внимание, что f a
аргумент был удален, fmap
поскольку, поскольку это язык ОО, вы вызываете этот метод для объекта. Этот интерфейс предполагает, что f a
аргумент был исправлен.