Scala 3:暗黙的なものを取り除く。型クラス







私の以前の記事は、暗黙の変換と拡張メソッドについてでした。この記事では、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



.








All Articles