Skip to main content

Programación genérica en Scala

⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.


El polimorfismo paramétrico es un concepto ampliamente utilizado también en Scala, que comparte varias similitudes con Kotlin en cuanto al soporte para tipos genéricos. Scala es un lenguaje de programación que combina paradigmas de programación funcional y orientada a objetos, y su sistema de tipos es extremadamente poderoso y flexible.

Función Genérica en Scala

En Scala, al igual que en Kotlin, podemos definir una función de identidad utilizando tipos genéricos. El polimorfismo paramétrico permite que esta función trabaje con cualquier tipo de datos.

def identity[T](value: T): T = value

Uso

val intIdentity = identity(42)          // intIdentity's type is Int
val stringIdentity = identity("Hola") // stringIdentity's type is String

Clases Genéricas en Scala

En Scala, las clases genéricas se definen de manera similar a Kotlin. Podemos crear una clase Box que pueda contener un valor de cualquier tipo:

class Box[T](val value: T)

Uso

val intBox = new Box(123)
println(intBox.value) // Prints: 123

val stringBox = new Box("Scala")
println(stringBox.value) // Prints: Scala

Interfaces Genéricas en Scala

Scala también soporta interfaces genéricas a través de traits. Los traits en Scala son similares a las interfaces en Kotlin, y permiten definir contratos para diferentes implementaciones.

trait Repository[T] {
def save(item: T): Unit
def findById(id: Int): Option[T]
}

Luego, podemos implementar este trait para una clase UserRepository que gestione usuarios:

class UserRepository extends Repository[User] {
private val users = scala.collection.mutable.ListBuffer[User]()

def save(item: User): Unit = {
users += item
}

def findById(id: Int): Option[User] = {
users.find(user => user.id == id)
}
}

case class User(id: Int, name: String)

Uso

val userRepository = new UserRepository()
val user = User(1, "John Doe")

userRepository.save(user)
println(userRepository.findById(1)) // Imprime: Some(User(1, "John Doe"))

Higher-Kinded Types (Tipos de Clase Superior)

Scala soporta Higher-Kinded Types (HKTs), que permiten definir abstracciones genéricas sobre constructores de tipos. A diferencia de los genéricos comunes que aceptan tipos simples (List[A]), los HKTs aceptan tipos que ellos mismos toman parámetros (F[_]), lo que los hace clave en estructuras funcionales como functores y mónadas.

Ejemplo: Functor Genérico

trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}

Aquí, F[_] puede ser cualquier estructura como List o Option.

Implementación para List

object ListFunctor extends Functor[List] {
def map[A, B](fa: List[A])(f: A => B): List[B] = fa.map(f)
}

Comparación Final

CaracterísticaKotlinScala
Polimorfismo ParamétricoSoporte de tipos genéricosSoporte de tipos genéricos
Higher-Kinded Types (HKTs)No soportado nativamenteSoporte completo para HKTs
Traits/Interfaces Genéricasinterface Repository<T>trait Repository[T]
Clases Genéricasclass Box<T>(val value: T)class Box[T](val value: T)
Funciones Genéricasfun <T> identity(value: T): Tdef identity[T](value: T): T
Ventajas de Scala
  1. Soporte para HKTs: Scala permite crear abstracciones sobre constructores de tipos, lo que facilita la implementación de patrones funcionales avanzados.
  2. Sistema de tipos más poderoso: Scala es conocido por su sistema de tipos expresivo, que permite construir estructuras más avanzadas.
Desventajas de Scala
  1. Curva de aprendizaje: El sistema de tipos avanzado y el soporte para HKTs pueden aumentar la complejidad y la curva de aprendizaje.

Bibliografías Recomendadas

  • 📚 "Scala Type System". (2022). David Pollak, Vishal Layka, & Andres Sacco, en Beginning Scala 3: A Functional and Object-Oriented Java Language, (pp. 197–218.) Apress Media, LLC.
  • 📰 "Higher-Kinded Types." Baeldung on Scala, 3 de agosto de 2020. https://www.baeldung.com/scala/higher-kinded-types