In Scala, how to use Ordering[T] with List.min or List.max and keep code readable

前端 未结 6 576
轮回少年
轮回少年 2020-12-23 20:58

In Scala 2.8, I had a need to call List.min and provide my own compare function to get the value based on the second element of a Tuple2. I had to write this kind of code:

6条回答
  •  盖世英雄少女心
    2020-12-23 22:03

    The function Ordering#on witnesses the fact that Ordering is a contra-variant functor. Others include Comparator, Function1, Comparable and scalaz.Equal.

    Scalaz provides a unified view on these types, so for any of them you can adapt the input with value contramap f, or with symbolic denotation, value ∙ f

    scala> import scalaz._
    import scalaz._
    
    scala> import Scalaz._
    import Scalaz._
    
    scala> val ordering = implicitly[scala.Ordering[Int]] ∙ {x: (_, Int) => x._2}
    ordering: scala.math.Ordering[Tuple2[_, Int]] = scala.math.Ordering$$anon$2@34df289d
    
    scala> List(("1", 1), ("2", 2)) min ordering  
    res2: (java.lang.String, Int) = (1,1)
    

    Here's the conversion from the Ordering[Int] to Ordering[(_, Int)] in more detail:

    scala> scalaz.Scalaz.maContravariantImplicit[Ordering, Int](Ordering.Int).contramap { x: (_, Int) => x._2 }
    res8: scala.math.Ordering[Tuple2[_, Int]] = scala.math.Ordering$$anon$2@4fa666bf
    

提交回复
热议问题