Acho que não entendo classes de tipo. Eu li em algum lugar que pensar em classes de tipo como "interfaces" (do OO) implementadas por um tipo é errado e enganoso. O problema é que estou tendo problemas para vê-los como algo diferente e como isso está errado.
Por exemplo, se eu tiver uma classe de tipo (na sintaxe Haskell)
class Functor f where
fmap :: (a -> b) -> f a -> f b
Como isso é diferente da interface [1] (na sintaxe Java)
interface Functor<A> {
<B> Functor<B> fmap(Function<B, A> fn)
}
interface Function<Return, Argument> {
Return apply(Argument arg);
}
Uma possível diferença em que posso pensar é que a implementação da classe de tipo usada em uma determinada invocação não é especificada, mas sim determinada a partir do ambiente - por exemplo, examinando os módulos disponíveis para uma implementação para esse tipo. Esse parece ser um artefato de implementação que pode ser endereçado em uma linguagem OO; como o compilador (ou o tempo de execução) poderia procurar um wrapper / extensor / monkey-patcher que exponha a interface necessária no tipo.
o que estou perdendo?
[1] Observe que o f a
argumento foi removido fmap
porque, como é uma linguagem OO, você chamaria esse método em um objeto. Essa interface assume que o f a
argumento foi corrigido.