En el nivel básico, no hay mucha diferencia, pero todavía están allí.
Haskell describe funciones o valores definidos en una clase de tipos como 'métodos', del mismo modo que los rasgos describen métodos OOP en los objetos que encierran. Sin embargo, Haskell se ocupa de estos de manera diferente, tratándolos como valores individuales en lugar de fijarlos a un objeto como OOP lo llevaría a hacerlo. Esta es la diferencia de nivel de superficie más obvia que existe.
Lo único que Rust no pudo hacer por un tiempo fueron los rasgos mecanografiados de orden superior , como las clases infames Functor
y Monad
tipográficas.
Esto significa que los rasgos de óxido solo podrían describir lo que a menudo se llama un "tipo concreto", en otras palabras, uno sin un argumento genérico. Haskell desde el principio podría crear clases de tipos de orden superior que usan tipos similares a cómo las funciones de orden superior usan otras funciones: usar una para describir otra. Durante un período de tiempo esto no fue posible en Rust, pero desde que se implementaron los elementos asociados , estos rasgos se han vuelto comunes e idiomáticos.
Entonces, si ignoramos las extensiones, no son exactamente las mismas, pero cada una puede aproximarse a lo que la otra puede hacer.
También es mencionable, como se dijo en los comentarios, que GHC (compilador principal de Haskell) admite más opciones para clases de tipos, incluidas clases de tipos de parámetros múltiples (es decir, muchos tipos involucrados) y dependencias funcionales , una opción encantadora que permite cálculos a nivel de tipo , y lleva a escribir familias . Que yo sepa, Rust no tiene funDeps ni familias de tipos, aunque puede que en el futuro. †
En general, los rasgos y las clases de tipos tienen diferencias fundamentales que, debido a la forma en que interactúan, los hacen actuar y parecer bastante similares al final.
† Puede encontrar un buen artículo sobre las clases de tipos de Haskell (incluidas las de tipo superior) aquí , y el capítulo Rust by Example sobre rasgos puede encontrarse aquí
class Functor f where fmap :: (a -> b) -> (f a -> f b)
; Un ejemplo de esto último esclass Bounded a where maxBound :: a
.