Scala Tour Implicit Conversion Example

前端 未结 1 1402
抹茶落季
抹茶落季 2021-01-27 02:34

I am having a hard time understanding what this piece of code does exactly:

import scala.language.implicitConversions

implicit def list2ordered[A](x: List[A])
           


        
相关标签:
1条回答
  • 2021-01-27 03:19

    Your confusion is understandable. The example code isn't terribly illuminating largely because the code, as presented, doesn't need the A-to-Ordered[A] conversion. We can comment it out and everything still "works" (such as it is).

    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
      }
    

    We can even implement a meaningful (if rather simple minded) List ordering and still not need the A-to-Ordered[A] conversion.

    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
      }
    

    But if List order depends on element order, then we need that conversion.

    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
        }
      }
    

    Just to drive home the point, let's simplify this order-by-3rd-element arrangement by modifying the required conversion.

    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
      }
    
    0 讨论(0)
提交回复
热议问题