Comment fonctionne la commande implicite [Option [T]] dans scala?
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
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