Scala Tour Implicit Conversion Example

安稳与你 提交于 2021-02-05 07:46:15

问题


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])
    (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
  }

It comes from the Scala Tour and it is in the section "Implicit Conversions". I understand that list2ordered takes a List[A] that comes from the left hand side of List(1, 2, 3) <= List(4, 5) and that in compare function is the right hand side.

However, why is A => Ordered[A] that and not List[A] => Ordered[List[A]] ? I am a bit confused as to what this piece of code actually does.


回答1:


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
  }


来源:https://stackoverflow.com/questions/63007728/scala-tour-implicit-conversion-example

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!