【问题标题】:Type parameter to ensure relational operators类型参数以确保关系运算符
【发布时间】:2020-07-11 11:31:33
【问题描述】:

我一直在尝试确定如何编写一个类型参数,将函数限制为支持关系运算符的类型?

例如:

def biggerOf[A <: ???](a: A, b: A): A = { if (a > b) a else b }

??? 是我的难题。高级类型参数位对我来说是新的,所以寻求一点帮助。认为 AnyVal 可能是赢家,但对于 Unit 类型(和 Boolean 不会破坏,但也不会工作)。感谢您的任何想法。

【问题讨论】:

    标签: scala generics types


    【解决方案1】:

    您想要使用 Ordering 类型类。

    import scala.math.Ordering.Implicits.infixOrderingOps
    
    def biggerOf[A:Ordering](a: A, b: A): A = { if (a > b) a else b }
    

    A:OrderingA 限制为Ordering 类型类中的类型,infixOrderingOps 启用便利运算符(方法),例如&lt;&gt;= 等。

    【讨论】:

      【解决方案2】:

      您可以使用orderingtypeclass

      def biggerOf[A : Ordering](a: A, b: A): A = {
        import Ordering.Implicits._
        if (a > b) a else b
      }
      

      【讨论】:

      • 超酷 - jwvh 比你略胜一筹。我更喜欢这里的导入风格,但显式导入确实使答案更加清晰。很好看!谢谢。
      • @reverend 通过特定名称导入隐式通常被认为是一种不好的做法,因为作者可以随时更改它,而您永远不会用他们的名字来引用他们。
      • \ Miguel\ Mejía\ Suárez - 有效点。我只是想说,看到scala.math.Ordering.Implicits.infixOrderingOps 让我非常清楚使这些解决方案起作用的基本“什么”就是全部。
      【解决方案3】:

      正如 Luis 和 jwvh 所建议的,您可以使用 Ordering 类型类,但我想向您介绍类型类模式并使用类型类来更深入地限制函数的使用。

      类型类允许一个人在其泛型类型中具有灵活性,同时对其进行足够的限制,以至于那些没有该类型类实例的人可能无法使用您的函数。

      以这个为例,假设 Scala 中的 Numerical 数据类型上没有操作符,我们可以通过引入 Num 类型类,然后通过指定它们在操作上的行为来概括对它们进行操作的想法,因为这些 Numerical数据类型有不同的处理代数运算的方法。 (例如整数与实数)

      trait Num[A] {
      
        def add(l: A, r: A): A
        def sub(l: A, r: A): A
        def mul(l: A, r: A): A
        def div(l: A, r: A): A
      
      }
      
      object NumTest {
        def addThenMultiply[A](l: A, r: A)(implicit ev: Num[A]): A =
          ev.mul(ev.add(l, r), r)
      
        //then we create Num instances for numerical types
      
        implicit val intNum = new Num[Int] { /* implementation*/ }
        implicit val floatNum = new Num[Float] { /* implementation */ }
      }
      

      现在在这种情况下,函数 addThenMultiply 仅适用于 IntFloat 数据类型,因为它们是唯一具有 Num 实例的函数,但您也可以为其他自定义数据类型添加实例,具体取决于根据您的需要。

      【讨论】:

      • 虽然这是一个很好的答案,但有点跑题了,最好自己做 Ordering,所以至少你会解决 OP 问题。另外,我的答案链接到类似的基本介绍。
      猜你喜欢
      • 1970-01-01
      • 2020-11-19
      • 2013-06-13
      • 1970-01-01
      • 2017-04-07
      • 2015-03-27
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多