Traits en Rust y Typeclasses en Haskell: batalla de abstracciones

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué comparar Rust y Haskell?

\n\n

Si alguna vez has mirado en Stack Overflow buscando una respuesta a la pregunta "What is the difference between traits in Rust and typeclasses in Haskell?", sabes que es un tema candente. Miles de visitas, decenas de votos: la comunidad de desarrolladores realmente quiere entender en qué se diferencian estos dos mecanismos.

\n\n

A primera vista, se parecen como hermanos: tanto los traits en Rust como las typeclasses en Haskell permiten definir un comportamiento común para diferentes tipos. Pero si profundizas, descubres que la filosofía, implementación y aplicación práctica son universos distintos.

\n\n

En este artículo, analizaremos las diferencias clave con ejemplos reales de código en Rust (con algunas pinceladas de Haskell para contrastar), y al final tendrás una comprensión clara de: cuándo usar traits y dónde es mejor pensar en un enfoque similar a typeclass.

\n\n

Breve resumen: ¿qué son los traits en Rust?

\n\n

Los traits en Rust son una forma de declarar un conjunto de métodos que deben ser implementados para un tipo específico. Son la base de la programación genérica (generics) y del polimorfismo en Rust.

\n\n

Un ejemplo simple: imagina que queremos que diferentes tipos puedan "saludar".

\n\n
trait Greeter {\n    fn greet(&self) -> String;\n}\n\nstruct Person {\n    name: String,\n}\n\nimpl Greeter for Person {\n    fn greet(&self) -> String {\n        format!("¡Hola, me llamo {}!", self.name)\n    }\n}\n\nstruct Robot {\n    model: String,\n}\n\nimpl Greeter for Robot {\n    fn greet(&self) -> String {\n        format!("Bip-bop, modelo: {}", self.model)\n    }\n}\n\nfn say_hello(item: &impl Greeter) {\n    println!("{}", item.greet());\n}\n\nfn main() {\n    let person = Person { name: "Ana".into() };\n    let robot = Robot { model: "R2-D2".into() };\n    say_hello(&person);\n    say_hello(&robot);\n}
\n\n

Aquí, Greeter es un trait. Los tipos Person y Robot lo implementan a su manera. La función say_hello acepta cualquier tipo que implemente Greeter. Esto es polimorfismo a través de traits.

\n\n

Breve resumen: ¿qué son las typeclasses en Haskell?

\n\n

Una typeclass en Haskell es una interfaz que define un conjunto de funciones que pueden ser implementadas para diferentes tipos. Suena familiar, ¿verdad?

\n\n

Así se vería un ejemplo similar en Haskell:

\n\n
class Greeter a where\n    greet :: a -> String\n\ndata Person = Person { name :: String }\ndata Robot = Robot { model :: String }\n\ninstance Greeter Person where\n    greet (Person n) = "¡Hola, me llamo " ++ n ++ "!"\n\ninstance Greeter Robot where\n    greet (Robot m) = "Bip-bop, modelo: " ++ m\n\nsayHello :: Greeter a => a -> IO ()\nsayHello item = putStrLn (greet item)\n\nmain = do\n    sayHello (Person "Ana")\n    sayHello (Robot "R2-D2")
\n\n

La sintaxis es diferente, pero la lógica es la misma. Y sin embargo, las diferencias entre traits en Rust y typeclasses en Haskell comienzan precisamente aquí.

\n\n

Diferencia clave n.º 1: Monomorfización vs boxing (Box)

\n\n

La diferencia más fundamental entre traits y typeclasses radica en cómo el compilador maneja el código genérico.

\n\n

Rust: monomorfización

\n\n

Cuando escribes fn say_hello(item: &impl Greeter), el compilador de Rust crea una copia separada de la función para cada tipo concreto. Esto se llama monomorfización. Resultado: abstracción de costo cero (zero-cost abstraction): no pagas por lo que no usas. Pero el tamaño del código puede aumentar.

\n\n

Haskell: boxing (por defecto)

\n\n

En Haskell, las typeclasses generalmente se implementan mediante diccionarios de métodos (vtable). El compilador pasa un parámetro implícito: una tabla con punteros a funciones. Esto se llama boxing. Pagas por la

Blogs

Book Recommendations