Ketik Lambda pada konteks terikat dan peran tipe alias

Sep 19 2020

Saya harus menulis konteks yang terikat untuk Pemesanan [Option [T]]

ternyata solusinya adalah

def test[T: ({type L[x] = Ordering[Option[x]]})#L](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}

lihat Bagaimana mendefinisikan konteks yang terikat dengan jenis yang lebih tinggi (Type Constructor)

Jadi bermain dengan tipe lambda sedikit untuk lebih memahami, mengarahkan saya untuk menulis versi tanpa tipe lambda:

type L[x] = Ordering[Option[x]]

def testN[T: L](value1: Option[T], value2: Option[T]) = {
  implicitly[L[T]].compare(value1, value2)
}

Banyak contoh penggunaan Type lambda adalah untuk konstruktor tipe dengan 2 parameter seperti MAP [K, V].

Dalam hal ini kami tidak memiliki masalah itu.

Jadi saya hanya bertanya-tanya, mengapa tidak memiliki yang seperti ini

def test[T: Ordering[Option]](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}

jelas itu tidak berhasil. Saya rasa saya mengerti intinya, tidak ada tipe konstruktor yang Ordering[Option[_]]ditentukan.

Yang kami miliki dalam pemesanan adalah:

trait OptionOrdering[T] extends Ordering[Option[T]] {
    def optionOrdering: Ordering[T]
    def compare(x: Option[T], y: Option[T]) = (x, y) match {
      case (None, None)       => 0
      case (None, _)          => -1
      case (_, None)          => 1
      case (Some(x), Some(y)) => optionOrdering.compare(x, y)
    }
  }
  implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
    new OptionOrdering[T] { val optionOrdering = ord }

Seperti berdiri Ordering[Option[T]]dalam definisi di atas, adalah Ordering[Option[T]] forSome {type T}akka Eksistensial, oleh karena itu merupakan tipe yang tepat, dan bukan tipe konstruktor.

Jadi jika saya benar apa yang kita lakukan di sini:

({type L[x] = Ordering[Option[x]]})#L

atau di sini:

type L[x] = Ordering[Option[x]]

sedang mendefinisikan Pembuat Jenis Ordering[Option[_]].

Pertanyaan 1:

1 - apakah pemahaman saya benar? apakah itu yang dilakukan Type Lambda di sini?

2 - Saya agak bingung di sini, jadi alias tipe adalah sesuatu yang memungkinkan Anda membuat konstruktor tipe dari komposisi konstruktor tipe lain. Dalam arti saya mencoba untuk memahami peran formal alias tipe dengan variabel tipe.

scala> type e0 = Ordering[Option[_]]
defined type alias e0

scala> :kind -v e0
e0's kind is A
*
This is a proper type.
scala> type e1[w] = Ordering[Option[w]]
defined type alias e1

scala> :kind -v e1
e1's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.

scala> 

Jawaban

3 MarioGalic Sep 19 2020 at 04:33

Konstruktor tipe anonim

({type L[x] = Ordering[Option[x]]})#L

adalah untuk bernama konstruktor tipe

type L[x] = Ordering[Option[x]]

apa konstruktor anonim (nilai)

(x: Int) => x + 1

adalah untuk bernama (nilai) konstruktor

val f = (x: Int) => x + 1

sebagai contoh

scala> lazy val v: (({type L[x] = Ordering[Option[x]]})#L)[Int] = ???
lazy val v: scala.math.Ordering[Option[Int]] // unevaluated

scala> lazy val v: L[Int] = ???
lazy val v: L[Int] // unevaluated

scala> lazy val v = ((x: Int) => x + 1)(41)
lazy val v: Int // unevaluated

scala> lazy val v = f(41)
lazy val v: Int // unevaluated

Di Scala 3 (Dotty) Anda akan bisa mengganti "kekejaman"

Ada lebih sedikit kebutuhan untuk proyektor jenis dalam keadaan kotor karena kami memiliki jenis lambda asli daripada kekejaman yang melibatkan jenis struktural.

dengan sintaks lambda tipe yang indah

Starting dotty REPL...
scala> lazy val v: (({type L[x] = Ordering[Option[x]]})#L)[Int] = ???
lazy val v: Ordering[Option[Int]]

scala> lazy val v: ([x] =>> Ordering[Option[x]])[Int] = ???
lazy val v: Ordering[Option[Int]]

Sintaks terikat konteks

def test[T: ({type L[x] = Ordering[Option[x]]})#L](value1: Option[T], value2: Option[T]) = ???

setara dengan

def test[T](value1: Option[T], value2: Option[T])(implicit ev: (({type L[x] = Ordering[Option[x]]})#L)[T]) = ???

yang disederhanakan menjadi

def test[T](value1: Option[T], value2: Option[T])(implicit ev: Ordering[Option[T]]) = ???