Skip to content

Commit 4a0dca4

Browse files
Add ca given imports in ru (#2884)
* Update compound-types.md in russian * Add ca-given-imports.md in ru * Add ca-given-imports.md in ru * Add ca-type-classes.md in ru
1 parent 791acfa commit 4a0dca4

File tree

5 files changed

+287
-3
lines changed

5 files changed

+287
-3
lines changed

_overviews/scala3-book/ca-given-imports.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Given Imports
33
type: section
44
description: This page demonstrates how 'given' import statements work in Scala 3.
5-
languages: [zh-cn]
5+
languages: [ru, zh-cn]
66
num: 63
77
previous-page: ca-context-bounds
88
next-page: ca-type-classes

_overviews/scala3-book/ca-type-classes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Type Classes
33
type: section
44
description: This page demonstrates how to create and use type classes.
5-
languages: [zh-cn]
5+
languages: [ru, zh-cn]
66
num: 64
77
previous-page: ca-given-imports
88
next-page: ca-multiversal-equality

_ru/scala3/book/ca-context-bounds.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: В этой главе представлены контекстн
99
language: ru
1010
num: 62
1111
previous-page: ca-context-parameters
12-
next-page:
12+
next-page: ca-given-imports
1313
---
1414

1515
Во многих ситуациях имя [контекстного параметра]({% link _overviews/scala3-book/ca-context-parameters.md %}#context-parameters)

_ru/scala3/book/ca-given-imports.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
layout: multipage-overview
3+
title: Given импорты
4+
scala3: true
5+
partof: scala3-book
6+
overview-name: "Scala 3 — Book"
7+
type: section
8+
description: На этой странице показано, как работают операторы импорта 'given' в Scala 3.
9+
language: ru
10+
num: 63
11+
previous-page: ca-context-bounds
12+
next-page: ca-type-classes
13+
versionSpecific: true
14+
---
15+
16+
Для большей ясности, откуда берутся данные в текущей области видимости,
17+
для импорта экземпляров `given` используется специальная форма оператора `import`.
18+
Базовая форма показана в этом примере:
19+
20+
```scala
21+
object A:
22+
class TC
23+
given tc: TC = ???
24+
def f(using TC) = ???
25+
26+
object B:
27+
import A.* // импорт всех не-given элементов
28+
import A.given // импорт экземпляров given
29+
```
30+
31+
В этом коде предложение `import A.*` объекта `B` импортирует все элементы `A`, _кроме_ `given` экземпляра `tc`.
32+
И наоборот, второй импорт, `import A.given`, импортирует _только_ экземпляр `given`.
33+
Два предложения импорта также могут быть объединены в одно:
34+
35+
```scala
36+
object B:
37+
import A.{given, *}
38+
```
39+
40+
## Обсуждение
41+
42+
Селектор с подстановочным знаком `*` помещает в область видимости все определения, кроме given-ов или расширений,
43+
тогда как селектор `given` помещает в область видимости _все_ given-ы, включая те, которые являются результатом расширений.
44+
45+
Эти правила имеют два основных преимущества:
46+
47+
- понятнее, откуда берутся данные в текущей области видимости.
48+
В частности, невозможно скрыть импортированные given-ы в длинном списке других импортов.
49+
- есть возможность импортировать все given, не импортируя ничего другого.
50+
Это важно, потому что given-ы могут быть анонимными, поэтому обычное использование именованного импорта нецелесообразно.
51+
52+
Дополнительные примеры синтаксиса "import given" показаны в главе ["Пакеты и импорт"][imports].
53+
54+
[imports]: {% link _overviews/scala3-book/packaging-imports.md %}

_ru/scala3/book/ca-type-classes.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
---
2+
layout: multipage-overview
3+
title: Классы типов
4+
scala3: true
5+
partof: scala3-book
6+
overview-name: "Scala 3 — Book"
7+
type: section
8+
description: В этой главе демонстрируется создание и использование классов типов.
9+
language: ru
10+
num: 64
11+
previous-page: ca-given-imports
12+
next-page:
13+
---
14+
15+
Класс типов (_type class_) — это абстрактный параметризованный тип,
16+
который позволяет добавлять новое поведение к любому закрытому типу данных без использования подтипов.
17+
Если вы пришли с Java, то можно думать о классах типов как о чем-то вроде [`java.util.Comparator[T]`][comparator].
18+
19+
> В статье ["Type Classes as Objects and Implicits"][typeclasses-paper] (2010 г.) обсуждаются основные идеи,
20+
> лежащие в основе классов типов в Scala.
21+
> Несмотря на то, что в статье используется более старая версия Scala, идеи актуальны и по сей день.
22+
23+
Этот стиль программирования полезен во многих случаях, например:
24+
25+
- выражение того, как тип, которым вы не владеете, например, из стандартной или сторонней библиотеки, соответствует такому поведению
26+
- добавление поведения к нескольким типам без введения отношений подтипов между этими типами (например, когда один расширяет другой)
27+
28+
Классы типов — это трейты с одним или несколькими параметрами,
29+
реализации которых предоставляются в виде экземпляров `given` в Scala 3 или `implicit` значений в Scala 2.
30+
31+
## Пример
32+
33+
Например, `Show` - хорошо известный класс типов в Haskell, и в следующем коде показан один из способов его реализации в Scala.
34+
Если предположить, что классы Scala не содержат метода `toString`, то можно определить класс типов `Show`,
35+
чтобы добавить это поведение к любому типу, который вы хотите преобразовать в пользовательскую строку.
36+
37+
### Класс типов
38+
39+
Первым шагом в создании класса типов является объявление параметризованного trait, содержащего один или несколько абстрактных методов.
40+
Поскольку `Showable` содержит только один метод с именем `show`, он записывается так:
41+
42+
{% tabs 'definition' class=tabs-scala-version %}
43+
{% tab 'Scala 2' %}
44+
45+
```scala
46+
// класс типов
47+
trait Showable[A] {
48+
def show(a: A): String
49+
}
50+
```
51+
52+
{% endtab %}
53+
{% tab 'Scala 3' %}
54+
55+
```scala
56+
// класс типов
57+
trait Showable[A]:
58+
extension (a: A) def show: String
59+
```
60+
61+
{% endtab %}
62+
{% endtabs %}
63+
64+
Обратите внимание, что этот подход близок к обычному объектно-ориентированному подходу,
65+
когда обычно trait `Show` определяется следующим образом:
66+
67+
{% tabs 'trait' class=tabs-scala-version %}
68+
{% tab 'Scala 2' %}
69+
70+
```scala
71+
// a trait
72+
trait Show {
73+
def show: String
74+
}
75+
```
76+
77+
{% endtab %}
78+
{% tab 'Scala 3' %}
79+
80+
```scala
81+
// a trait
82+
trait Show:
83+
def show: String
84+
```
85+
86+
{% endtab %}
87+
{% endtabs %}
88+
89+
Следует отметить несколько важных моментов:
90+
91+
1. Классы типов, например, `Showable` принимают параметр типа `A`, чтобы указать, для какого типа мы предоставляем реализацию `show`;
92+
в отличие от классических трейтов, наподобие `Show`.
93+
2. Чтобы добавить функциональность `show` к определенному типу `A`, классический трейт требует наследования `A extends Show`,
94+
в то время как для классов типов нам требуется реализация `Showable[A]`.
95+
3. В Scala 3, чтобы разрешить один и тот же синтаксис вызова метода в обоих случаях `Showable`,
96+
который имитирует синтаксис `Show`, мы определяем `Showable.show` как метод расширения.
97+
98+
### Реализация конкретных экземпляров
99+
100+
Следующий шаг — определить, какие классы `Showable` должны работать в вашем приложении, а затем реализовать для них это поведение.
101+
Например, для реализации `Showable` следующего класса `Person`:
102+
103+
{% tabs 'person' %}
104+
{% tab 'Scala 2 и 3' %}
105+
106+
```scala
107+
case class Person(firstName: String, lastName: String)
108+
```
109+
110+
{% endtab %}
111+
{% endtabs %}
112+
113+
необходимо определить одно _каноническое значение_ типа `Showable[Person]`, т.е. экземпляр `Showable` для типа `Person`,
114+
как показано в следующем примере кода:
115+
116+
{% tabs 'instance' class=tabs-scala-version %}
117+
{% tab 'Scala 2' %}
118+
119+
```scala
120+
implicit val showablePerson: Showable[Person] = new Showable[Person] {
121+
def show(p: Person): String =
122+
s"${p.firstName} ${p.lastName}"
123+
}
124+
```
125+
126+
{% endtab %}
127+
{% tab 'Scala 3' %}
128+
129+
```scala
130+
given Showable[Person] with
131+
extension (p: Person) def show: String =
132+
s"${p.firstName} ${p.lastName}"
133+
```
134+
135+
{% endtab %}
136+
{% endtabs %}
137+
138+
### Использование класса типов
139+
140+
Теперь вы можете использовать этот класс типов следующим образом:
141+
142+
{% tabs 'usage' class=tabs-scala-version %}
143+
{% tab 'Scala 2' %}
144+
145+
```scala
146+
val person = Person("John", "Doe")
147+
println(showablePerson.show(person))
148+
```
149+
150+
Обратите внимание, что на практике классы типов обычно используются со значениями, тип которых неизвестен,
151+
в отличие от type `Person`, как показано в следующем разделе.
152+
153+
{% endtab %}
154+
{% tab 'Scala 3' %}
155+
156+
```scala
157+
val person = Person("John", "Doe")
158+
println(person.show)
159+
```
160+
161+
{% endtab %}
162+
{% endtabs %}
163+
164+
Опять же, если бы в Scala не было метода `toString`, доступного для каждого класса, вы могли бы использовать эту технику,
165+
чтобы добавить поведение `Showable` к любому классу, который вы хотите преобразовать в `String`.
166+
167+
### Написание методов, использующих класс типов
168+
169+
Как и в случае с наследованием, вы можете определить методы, которые используют `Showable` в качестве параметра типа:
170+
171+
{% tabs 'method' class=tabs-scala-version %}
172+
{% tab 'Scala 2' %}
173+
174+
```scala
175+
def showAll[A](as: List[A])(implicit showable: Showable[A]): Unit =
176+
as.foreach(a => println(showable.show(a)))
177+
178+
showAll(List(Person("Jane"), Person("Mary")))
179+
```
180+
181+
{% endtab %}
182+
{% tab 'Scala 3' %}
183+
184+
```scala
185+
def showAll[A: Showable](as: List[A]): Unit =
186+
as.foreach(a => println(a.show))
187+
188+
showAll(List(Person("Jane"), Person("Mary")))
189+
```
190+
191+
{% endtab %}
192+
{% endtabs %}
193+
194+
### Класс типов с несколькими методами
195+
196+
Обратите внимание: если вы хотите создать класс типов с несколькими методами, исходный синтаксис выглядит следующим образом:
197+
198+
{% tabs 'multiple-methods' class=tabs-scala-version %}
199+
{% tab 'Scala 2' %}
200+
201+
```scala
202+
trait HasLegs[A] {
203+
def walk(a: A): Unit
204+
def run(a: A): Unit
205+
}
206+
```
207+
208+
{% endtab %}
209+
{% tab 'Scala 3' %}
210+
211+
```scala
212+
trait HasLegs[A]:
213+
extension (a: A)
214+
def walk(): Unit
215+
def run(): Unit
216+
```
217+
218+
{% endtab %}
219+
{% endtabs %}
220+
221+
### Пример из реального мира
222+
223+
В качестве примера из реального мира, как классы типов используются в Scala 3,
224+
см. обсуждение `CanEqual` в [разделе Multiversal Equality][multiversal].
225+
226+
[typeclasses-paper]: https://infoscience.epfl.ch/record/150280/files/TypeClasses.pdf
227+
228+
[typeclasses-chapter]: {% link _overviews/scala3-book/ca-type-classes.md %}
229+
[comparator]: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
230+
[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %}

0 commit comments

Comments
 (0)