私の以前の記事は、暗黙の変換と拡張メソッドについてでした。この記事では、Scala3で型クラスを宣言する新しい方法について説明します。
外部メソッドを任意のクラスに追加する方法を学んだので、さらに深く掘り下げたいと思います。つまり、任意のクラスを「外部」インターフェースに変換する方法、つまり、それらから直接継承しない方法を学びたいと思います。このタスクは型クラスによって解決されます。
しかし、最初に、型クラスが何であるかを理解しましょう。概念自体と同様に、「型クラス」という用語はHaskellに由来します。ここで「クラス」という言葉は、OOPで受け入れられる狭い意味ではなく、広い意味で使用されます。つまり、共通点を持つ一連のエンティティの指定です。(この記事を読むほとんどの人はOOPのバックグラウンドを持っていることを理解しています。彼らにとって、「タイプクラス」という用語は「オイルのカテゴリ」を意味しますが、「オイルのオイル」のように聞こえます。従来のOOPクラスとの混同を避けるため、「型クラス」の代わりに、文字変換「型クラス」を使用します-約transl。)
例の構文は最新Scala 3.0.0-M3
です。
, , , . Scala 3:
// Adapted from this Dotty documentation:
// https://dotty.epfl.ch/docs/reference/contextual/type-classes.html
trait Semigroup[T]:
extension (t: T)
def combine(other: T): T
def <+>(other: T): T = t.combine(other)
trait Monoid[T] extends Semigroup[T]:
def unit: T
, <+>
. — , , 0 — . , Semigroup
Monoid
.
Semigroup
T
extension- combine
<+>
, combine
. unit
Monoid
, extension-. , unit
T
, , , T
, .
:
given StringMonoid: Monoid[String] with
def unit: String = ""
extension (s: String) def combine(other: String): String = s + other
given IntMonoid: Monoid[Int] with
def unit: Int = 0
extension (i: Int) def combine(other: Int): Int = i + other
. , given foo: Bar
— implicit-. Scala3 REPL, , : StringMonoid
IntMonoid
.
- :
"2" <+> ("3" <+> "4") // "234"
("2" <+> "3") <+> "4" // "234"
StringMonoid.unit <+> "2" // "2"
"2" <+> StringMonoid.unit // "2"
2 <+> (3 <+> 4) // 9
(2 <+> 3) <+> 4 // 9
IntMonoid.unit <+> 2 // 2
2 <+> IntMonoid.unit // 2
StringMonoid
IntMonoid
unit
. <+>
extension-, String
Int
. <+>
, .
: given Monoid[String] with ...
. unit
summon[Monoid[String]]
. summon
— implicitly
, implicit- . given_Monoid_String
, , .
, , - ( unit
). .
, . , , IntMonoid
Numeric[T]
:
given NumericMonoid[T](using num: Numeric[T]): Monoid[T] with
def unit: T = num.zero
extension (t: T) def combine(other: T): T = num.plus(t, other)
2.2 <+> (3.3 <+> 4.4) // 9.9
(2.2 <+> 3.3) <+> 4.4 // 9.9
BigDecimal(3.14) <+> NumericMonoid.unit
NumericMonoid[BigDecimal].unit <+> BigDecimal(3.14)
using
, Scala 2 implicit
. .
. NumericMonoid
— , Monoid[T]
— . T
, . NumericMonoid[BigDecimal]
, NumericMonoid
BigDecimal
. num
— NumericMonoid
, using
.
, unit
. -, <+>
. Scala obj1.method(obj2)
.
?
using
.