0Pricing
Scala for Backend Engineering & Functional Programming · Lekcja

Wyprowadzanie type class

Instancje automatyczne

Wyprowadzanie type class to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Czym jest wyprowadzanie instancji?

Wyprowadzanie instancji klasy typów automatycznie generuje instancje na podstawie struktury typu, dzięki czemu nie trzeba ręcznie pisać powtarzalnego kodu dla każdej klasy case. Kompilator tworzy instancję na podstawie jej pól.

Problem powtarzalnego kodu

Bez wyprowadzania każda nowa klasa case wymaga ręcznej instancji. W przypadku Show dla dwudziestu klas case oznacza to dwadzieścia niemal identycznych definicji. Wyprowadzanie eliminuje to powtórzenie.

Najpierw ręczne składanie

Zanim przejdziemy do automatycznego wyprowadzania, zauważmy, że instancje można ręcznie składać z instancji pól. To właśnie tę zasadę automatyzuje wyprowadzanie.

trait Show[A] { def show(a: A): String }

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

object Main {
  implicit val strShow: Show[String] = s => s
  implicit val intShow: Show[Int] = _.toString

  implicit val userShow: Show[User] = (u: User) =>
    s"User(${strShow.show(u.name)}, ${intShow.show(u.age)})"

  def main(args: Array[String]): Unit = {
    println(userShow.show(User("Ann", 30)))
  }
}

Instancje indukcyjne

Wyprowadzanie działa indukcyjnie: najpierw definiuje się instancje dla typów pierwotnych, a następnie łączy je dla produktów (klas case) i sum (zapieczętowanych traitów). Wyprowadzana instancja jest tworzona z tych elementów.

Słowo kluczowe derives w Scala 3

Scala 3 obsługuje klauzulę derives. Klasę typów z metodą derived można dołączyć do typu za pomocą jednego słowa kluczowego. (Fragment koncepcyjny; wymaga klasy typów obsługującej wyprowadzanie.)

enum Color derives CanEqual:
  case Red, Green, Blue

@main def run(): Unit =
  println(Color.Red == Color.Red)

Wyprowadzanie oparte na Mirror

Derywacja w Scali 3 wykorzystuje scala.deriving.Mirror, który udostępnia strukturę typu (typy i nazwy pól) w czasie kompilacji. Metoda derived składa instancje elementów lustra, aby zbudować całość.

Derywacja półautomatyczna

Biblioteki takie jak Cats oferują derywację półautomatyczną: włączają ją Państwo osobno dla każdego typu za pomocą jednolinijkowego wywołania, takiego jak deriveShow. Pozwala to zachować przewidywalny czas kompilacji i jednocześnie usunąć kod pomocniczy.

Automatyczna a półautomatyczna

Dwa style:

  • Automatyczna: instancje pojawiają się wszędzie tam, gdzie są potrzebne, za pośrednictwem importu implicit; jest to wygodne, ale może spowalniać kompilację.
  • Półautomatyczna: dla każdego typu piszą Państwo jedno jawne wywołanie derywacji; zapewnia to większą kontrolę i szybsze kompilacje.

Derywacja dla zapieczętowanych traitów

W przypadku zapieczętowanej hierarchii (typu sumy) wyprowadzona instancja wybiera działanie na podstawie tego, którym podtypem jest dana wartość. Poniższa wersja napisana ręcznie pokazuje ideę, którą automatyzuje derywacja.

trait Show[A] { def show(a: A): String }

sealed trait Shape
case class Circle(r: Int) extends Shape
case class Square(s: Int) extends Shape

object Main {
  implicit val shapeShow: Show[Shape] = {
    case Circle(r) => s"Circle($r)"
    case Square(s) => s"Square($s)"
  }

  def main(args: Array[String]): Unit = {
    println(shapeShow.show(Circle(5)))
    println(shapeShow.show(Square(3)))
  }
}

Kiedy stosować derywację

Warto zastosować derywację, gdy:

  • Mają Państwo wiele typów danych wymagających tej samej klasy typów (kodeków JSON, Show, Eq).
  • Instancję można mechanicznie wyprowadzić ze struktury.

Instancje należy pisać ręcznie, gdy zachowanie jest niestandardowe lub kluczowe dla wydajności.

Przykład generycznego porównywania równości

Równość jest klasycznym przykładem klasy typów, którą można wyprowadzić. Standardowe == dla klas przypadków jest właściwie rodzajem równości strukturalnej generowanej za Państwa przez kompilator.

case class Coord(x: Int, y: Int)

object Main {
  def main(args: Array[String]): Unit = {
    println(Coord(1, 2) == Coord(1, 2))
    println(Coord(1, 2) == Coord(3, 4))
  }
}

Szybki test

Proszę sprawdzić swoje rozumienie derywacji.

Podsumowanie

Poznali Państwo derywację klas typów:

  • Instancje są budowane indukcyjnie z instancji pól lub przypadków.
  • Scala 3 używa Mirror oraz słowa kluczowego derives.
  • Wygodę zapewnia derywacja automatyczna, a kontrolę — półautomatyczna.
  • Pozwala ona wyeliminować kod pomocniczy w wielu typach danych.

Często zadawane pytania

Czy lekcja „Wyprowadzanie type class” jest bezpłatna?

Tak — pełny tekst „Wyprowadzanie type class” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Co nauczysz się w „Wyprowadzanie type class”?

Instancje automatyczne Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?

Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wyprowadzanie type class”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?

Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wzorzec type class
  2. Definiowanie instancji
  3. Typowe type classy
  4. Wyprowadzanie type class
← Powrót do Scala for Backend Engineering & Functional Programming