Comment fonctionne la commande implicite [Option [T]] dans scala?

Sep 16 2020

Je joue un peu avec la résolution implicite, et je voulais comprendre à quoi sert ce val implicite? Lors de la commande, nous avons

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 }

Je me demande quand est implicite def Option [T] (implicite ord: Ordering [T]): Ordering [Option [T]] utile ou appelée.

J'ai essayé ce qui suit:

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

Mais le compilateur n'aime pas ça.

non trouvé: type T def test [Option [T]: Ordering] (valeur1: Option [T], valeur2: Option [T]) = {

Et si je fais ce qui est accordé pourrait ne pas avoir de sens mais juste pour le plaisir

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

I get 

type Option takes type parameters
def test[Option[Int]: Ordering](value1: Option[Int], value2: Option[Int]) = {
No implicit Ordering defined for Option[Int]

Quelqu'un peut-il donner un exemple de la façon d'utiliser cet implicite et ou où est-il utile et réellement utilisé?

Mon hypothèse est que quand il y a un besoin d'une commande [Option [T]] alors cette fonction est appelée pour résoudre l'implicite. Mais je ne peux pas y arriver ...

EDIT Eh bien, j'ai écrit ce qui suit qui a plus de sens

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

Alors ce que je ne comprends pas, c'est le problème lié au contexte avec

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

What's wrong with writing a context bound like that ?

Réponses

4 MarioGalic Sep 16 2020 at 21:01

Je me demande quand est implicite def Option [T] (implicite ord: Ordering [T]): Ordering [Option [T]] utile ou appelée.

Des méthodes implicites peuvent être utilisées pour construire des instances de classe de type à partir d'autres instances de classe de type, ce qui peut sauver le passe-partout

implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
  new OptionOrdering[T] { val optionOrdering = ord }

Par exemple, étant donné une instance de classe de type, Ordering[Int]la méthode implicite ci-dessus peut construire une instance de classe de type Ordering[Option[Int]]. (N'oubliez pas le implicitparamètre, sinon nous obtenons une conversion implicite qui est mal vue).

Quel est le problème avec [Option [T]: Commande]

La clé est de comprendre la différence entre le constructeur de type et le type approprié. Par exemple, Optionun constructeur de type peut construire un type approprié Option[Int]. La clause de paramètre de type [Option[T]: Ordering]dans votre définition

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T])

ne spécifie pas réellement le Optionconstructeur de type. Il se trouve que vous l'avez nommé de la même manière, mais ce que vous avez spécifié ressemble plus à

def test[F[T]: Ordering](value1: F[T], value2: F[T])

De plus, Tin F[T]ne peut pas être utilisé dans la liste des paramètres de méthode, donc en fait votre définition est plus comme ça

def test[F[_]: Ordering](value1: F[T], value2: F[T])

Maintenant, les erreurs devraient être plus claires; F[_]: Orderingnécessite une instance de classe de type Ordering[F]où Fest un constructeur de type mais il n'y a pas d'instances de classe de type car la définition de classe de type Orderingest

trait Ordering[T]

où Test un type approprié. Sinon, il serait défini quelque chose comme

trait Ordering[F[_]]

Un exemple d'une telle classe de type est Functor

trait Functor[F[_]]

Par conséquent, pour corriger syntaxiquement votre définition, essayez quelque chose comme

def test[T](value1: Option[T], value2: Option[T])(implicit ev: Ordering[Option[T]]) = {
  ev.compare(value1, value2)
}

test(Some(1), Some(42))
// res0: Int = -1

implicitly[Ordering[Option[Int]]].compare(Some(1), Some(42))
// res1: Int = -1

Ici test(Some(1), Some(42))équivaut à

test[Int](Some(1), Some(42))(Option[Int])
                                |
                         implicit method call