Scala-Tour隐式转换示例
我很难理解这段代码到底做了什么:Scala-Tour隐式转换示例,scala,Scala,我很难理解这段代码到底做了什么: import scala.language.implicitConversions implicit def list2ordered[A](x: List[A]) (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = new Ordered[List[A]] { //replace with a more useful implementation def
import scala.language.implicitConversions
implicit def list2ordered[A](x: List[A])
(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =
new Ordered[List[A]] {
//replace with a more useful implementation
def compare(that: List[A]): Int = 1
}
它来自Scala教程,位于隐式转换部分。我知道list2ordered获取了一个列表[a],它来自列表1、2、3的左侧,已排序[a],而不是列表[a]=>已排序的[a]?我对这段代码的实际功能有点困惑。您的困惑是可以理解的。示例代码并没有很好地说明问题,主要是因为所展示的代码不需要A到有序[A]的转换。我们可以对它进行评论,但一切都照旧
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
1 //this is always greater than that
}
我们甚至可以实现一个有意义的、但思想相当简单的列表排序,并且仍然不需要a到Ordered[a]转换
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
但如果列表顺序取决于元素顺序,那么我们需要这种转换
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
为了阐明这一点,让我们通过修改所需的转换来简化这种按第三元素排序的安排
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
你的困惑是可以理解的。示例代码并没有很好地说明问题,主要是因为所展示的代码不需要A到有序[A]的转换。我们可以对它进行评论,但一切都照旧
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
1 //this is always greater than that
}
我们甚至可以实现一个有意义的、但思想相当简单的列表排序,并且仍然不需要a到Ordered[a]转换
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
但如果列表顺序取决于元素顺序,那么我们需要这种转换
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
为了阐明这一点,让我们通过修改所需的转换来简化这种按第三元素排序的安排
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
//)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.length - ys.length //shorter List before longer List
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: A => Ordered[A]
): Ordered[List[A]] =
new Ordered[List[A]] {
//3rd element determines order
def compare(ys: List[A]): Int = (xs.lift(2),ys.lift(2)) match {
case (None,None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) =>
x compare y //implicit conversion needed
}
}
import scala.language.implicitConversions
implicit def list2ordered[A](xs: List[A]
)(implicit elem2ordered: Option[A] => Ordered[Option[A]]
): Ordered[List[A]] =
new Ordered[List[A]] {
def compare(ys: List[A]): Int =
xs.lift(2) compare ys.lift(2) //3rd element determines order
}
隐式转换的最终结果是一个有序的[List[a]]。但是,为了比较两个列表,您首先需要还可以比较它们的元素。因此,这种隐式转换需要从a到顺序[a]的转换的隐式证据-无论如何,不鼓励隐式转换,而且这个特定用例最好由类型类建模,而不是查找顺序隐式转换的最终结果是一个有序的[List[a]]。但是,为了比较两个列表,您首先需要还可以比较它们的元素。因此,这种隐式转换需要隐式证据来证明从a到顺序[a]的转换——无论如何,隐式转换是不被鼓励的,这个特定的用例最好由一个类型类来建模,而不是寻找顺序