Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-Tour隐式转换示例_Scala - Fatal编程技术网

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]的转换——无论如何,隐式转换是不被鼓励的,这个特定的用例最好由一个类型类来建模,而不是寻找顺序