Definición de instancias
Instancias implícitas
Definición de instancias es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
Definir instancias
Una instancia indica al compilador cómo se comporta una clase de tipos para un tipo concreto. En Scala, las instancias suelen marcarse como implicit (Scala 2) o declararse con given (Scala 3) para que se encuentren automáticamente.
Una instancia implicit val
Para una clase de tipos sencilla, basta con un implicit val. El compilador lo encuentra cuando una función necesita un Show[Int].
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"Int=$a"
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(123))
}
}implicitly: solicitar una instancia
implicitly[Show[Int]] pide al compilador que obtenga la instancia disponible en el ámbito. Resulta útil para comprobar que existe una instancia o para acceder directamente a ella.
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"<$a>"
def main(args: Array[String]): Unit = {
val s = implicitly[Show[Int]]
println(s.show(8))
}
}Instancias para tipos personalizados
Defina una instancia para su propia case class. La clase de datos permanece limpia; el formato reside en la instancia.
trait Show[A] { def show(a: A): String }
case class Point(x: Int, y: Int)
object Main {
implicit val pointShow: Show[Point] = (p: Point) => s"(${p.x}, ${p.y})"
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(Point(3, 4)))
}
}implicit def para instancias genéricas
Cuando una instancia depende de otra, use implicit def. Aquí, un Show[List[A]] se construye a partir de un Show[A].
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => a.toString
implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
(xs: List[A]) => xs.map(s.show).mkString("[", ", ", "]")
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(List(1, 2, 3)))
}
}Instancias en el objeto complementario
Colocar las instancias en el objeto complementario de la clase de tipos permite encontrarlas automáticamente sin ningún import. Este es el lugar recomendado para las instancias predeterminadas.
trait Show[A] { def show(a: A): String }
object Show {
implicit val intShow: Show[Int] = (a: Int) => s"i:$a"
implicit val strShow: Show[String] = (a: String) => s"s:$a"
}
object Main {
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(5))
println(display("hi"))
}
}Ámbito y prioridad de los implicit
El compilador busca una instancia en varios lugares: primero en el ámbito local o importado y después en los objetos complementarios de los tipos implicados. Si dos instancias tienen el mismo nivel de especificidad, se produce un error de implicit ambiguo.
Abreviatura de context bound
La sintaxis def f[A: Show](a: A) es un context bound: significa que debe haber un Show[A] implícito disponible en el ámbito. Dentro de la función, puede obtenerlo con implicitly.
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"n=$a"
def display[A: Show](a: A): String = implicitly[Show[A]].show(a)
def main(args: Array[String]): Unit = {
println(display(77))
}
}Un helper para solicitar instancias
Las bibliotecas añaden un método apply al objeto complementario como summoner práctico: Show[Int] devuelve la instancia. Es más limpio que implicitly.
trait Show[A] { def show(a: A): String }
object Show {
def apply[A](implicit s: Show[A]): Show[A] = s
implicit val intShow: Show[Int] = (a: Int) => s"=$a"
}
object Main {
def main(args: Array[String]): Unit = {
println(Show[Int].show(10))
}
}Evitar instancias huérfanas
Una instancia huérfana es aquella que no se define junto con la clase de tipos ni junto con el tipo. Son legales, pero pueden provocar un comportamiento incoherente entre distintos imports. Prefiera las instancias en objetos complementarios para mantener la coherencia.
Integrar todos los elementos
Un programa completo: instancias en el objeto complementario, una instancia derivada para listas y un summoner.
trait Show[A] { def show(a: A): String }
object Show {
def apply[A](implicit s: Show[A]): Show[A] = s
implicit val intShow: Show[Int] = _.toString
implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
(xs: List[A]) => xs.map(s.show).mkString(", ")
}
object Main {
def main(args: Array[String]): Unit = {
println(Show[List[Int]].show(List(4, 5, 6)))
}
}Comprobación rápida
Compruebe sus conocimientos sobre la definición de instancias.
Resumen
Ha aprendido a definir instancias:
implicit valpara instancias sencillas yimplicit defpara las derivadas.- Solicítelas con
implicitlyo con unapplydel objeto complementario. - Use context bounds
[A: Show]como abreviatura. - Coloque las instancias en objetos complementarios para evitar instancias huérfanas.
Preguntas frecuentes
¿La lección «Definición de instancias» es gratis?
Sí — el texto completo de «Definición de instancias» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
¿Qué aprenderé en «Definición de instancias»?
Instancias implícitas Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?
No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Definición de instancias»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?
Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- El patrón Type Class
- Definición de instancias
- Type Classes comunes
- Derivación de Type Classes