A livello base, non c'è molta differenza, ma sono ancora lì.
Haskell descrive funzioni o valori definiti in una typeclass come 'metodi', proprio come i tratti descrivono i metodi OOP negli oggetti che racchiudono. Tuttavia, Haskell si occupa di questi in modo diverso, trattandoli come valori individuali anziché fissarli a un oggetto come OOP porterebbe a fare. Si tratta della differenza di livello superficiale più evidente che ci sia.
L'unica cosa che Rust non poteva fare per un po 'erano tratti tipizzati di ordine superiore , come il famigerato Functor
e le Monad
macchine da scrivere.
Ciò significa che i tratti Rust potrebbero solo descrivere quello che spesso viene chiamato un "tipo concreto", in altre parole, senza un argomento generico. Haskell sin dall'inizio potrebbe creare macchine da scrivere di ordine superiore che usano tipi simili a come le funzioni di ordine superiore usano altre funzioni: usarne una per descriverne un'altra. Per un periodo di tempo ciò non è stato possibile in Rust, ma da quando gli articoli associati sono stati implementati, tali tratti sono diventati banali e idiomatici.
Quindi, se ignoriamo le estensioni, non sono esattamente le stesse, ma ognuna può approssimare ciò che l'altra può fare.
È anche menzionabile, come detto nei commenti, che GHC (il compilatore principale di Haskell) supporta ulteriori opzioni per le typeclass, tra cui le typeclass multiparametriche (cioè molti tipi coinvolti) e le dipendenze funzionali , una deliziosa opzione che consente calcoli a livello di tipo e porta a digitare famiglie . Per quanto ne sappia, Rust non ha né divertimenti né famiglie di tipi, anche se potrebbe in futuro. †
Tutto sommato, i tratti e le macchine da scrivere hanno differenze fondamentali, che a causa del modo in cui interagiscono, le fanno agire e sembrare abbastanza simili alla fine.
† Un bell'articolo sulle macchine da scrivere di Haskell (comprese quelle di tipo più alto) può essere trovato qui , e il capitolo Rust by Example sui tratti può essere trovato qui
class Functor f where fmap :: (a -> b) -> (f a -> f b)
; un esempio di quest'ultimo èclass Bounded a where maxBound :: a
.