Scala更改trait中定义的函数的参数

Scala更改trait中定义的函数的参数,scala,functional-programming,traits,companion-object,Scala,Functional Programming,Traits,Companion Object,因为我在任何地方都没有找到解决问题的方法,所以我想我可能是在想一个非常错误的方向 我的问题是: 我有一个特征a和另一个特征B,以及伴随对象AB1、AB2、AB3等等。单例对象扩展trait A,类扩展trait B。这些类的许多对象都在一个列表中 在这些对象上,我想使用在相应的singleton对象中定义的函数,这些函数接受与singleton对象相同类的对象 这是特征的一个例子: trait A { def compare(firstB: B, secondB: B) : Int }

因为我在任何地方都没有找到解决问题的方法,所以我想我可能是在想一个非常错误的方向

我的问题是: 我有一个特征a和另一个特征B,以及伴随对象AB1、AB2、AB3等等。单例对象扩展trait A,类扩展trait B。这些类的许多对象都在一个列表中

在这些对象上,我想使用在相应的singleton对象中定义的函数,这些函数接受与singleton对象相同类的对象

这是特征的一个例子:

trait A {
    def compare(firstB: B, secondB: B) : Int
}

trait B {}
和伴生物体:

class AB1(val variable: Int) extends B {}

object AB1 extends A {
    def apply(list: List[Int]): Option[AB1] = {
        if(list.foldLeft(0)(_ + _) < 10 && list.nonEmpty)
            some(new AB1(list.head))
        else
            null
    }
    override def compare(ab11: AB1, ab12: AB1): Int = {
        if(ab11 > ab12) 
            1
        else if(ab11 > ab12) 
            -1
        else 
            0
    }
}
在路上我遇到了两个问题:

  • b.getClass
    不等于
    AB1.getClass
    当b是类AB1的对象时。但这不是我的主要问题。我发现了一个使用字符串比较的解决方案,这真的很不漂亮,但现在,它可以工作了
  • 必须在trait中定义
    compare
    函数,因为否则它不能在扩展trait A的任何单例对象上强制转换。但是我发现没有办法用变量类型的参数定义函数
  • 我真的希望你能帮我解决这个问题

    编辑:现在我发现我忘了提一件事:

    我认为我必须更深入地了解我试图做的事情,以使您了解我的问题:

    我有一个
    列表[List[C]
    。那些
    C
    的列表可能能够用它创建一个AB1对象,但可能是AB2,也可能是AB3等等。所以我有

    val c: List[C] = (C1, C2, C4)
    val aList: List[A] = (AB1, AB2, AB3, ...)
    val bestB: B = (for{
        element <- aList
    } yield element  (c)).flatten.head   // Because the List aList is ordered: AB1 is the best case, AB2 the second best and so on.
    
    valc:List[c]=(C1、C2、C4)
    值列表:列表[A]=(AB1,AB2,AB3,…)
    val bestB:B=(对于{
    
    元素我认为您需要使用隐式
    比较器

    trait B
    case class AB1(variable: Int) extends B
    case class AB2(variable1: Int, variable2: Int) extends B
    
    implicit object AB1Comparator extends Comparator[AB1] {
      override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
    }
    
    implicit object AB2Comparator extends Comparator[AB2] {
      override def compare(o1: AB2, o2: AB2): Int = java.lang.Integer.compare(o1.variable1, o2.variable1) match {
        case 0 => java.lang.Integer.compare(o1.variable2, o2.variable2)
        case other => other
      }
    }
    
    def compare[A](obj1: A, obj2: A)(implicit comparator: Comparator[A]) = {
      comparator.compare(obj1, obj2)
    }
    
    val ab1List = List(AB1(1), AB1(2), AB1(3))
    val ab1Compare = compare(ab1List.head, ab1List.tail.head)
    
    val ab2List = List(AB2(1, 1), AB2(1, 1), AB2(1, 3))
    val ab2Compare = compare(ab2List.head, ab2List.tail.head)
    
    或者,如果要对列表进行排序,则应使用
    排序

    trait B
    case class AB1(variable: Int) extends B
    
    implicit object AB1Ordering extends Ordering[AB1] {
      override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
    }
    val ab1List = List(AB1(1), AB1(2), AB1(3))
    val ab1ListSorted = ab1List.sorted
    

    老实说,我仍然不明白你的根本问题是什么。但我会尽力回答我所理解的

    首先,如果您想在从trait重写函数时更改参数的类型。然后,答案是您不能!-因为这会破坏规则

    但是你可以用一个简单的方法实现你想要的

    现在,假设b11和b12是B1的实例,您只需编写

    implicitly[BComparator[B1]].compare(b11, b12)
    

    您好@SimonDose,这里有很多东西……首先,您不应该使用null,尤其是在您已经使用Option的情况下。其次,
    AB1.getClass
    b.getClass
    不同,因为AB1作为一个对象有它自己的类(即使它是一个伴生对象)第三,你不应该检查类实例,而应该使用模式匹配,这在Scala中更为惯用。最后,你能把你的问题说得更清楚一点吗?我已经读了三遍了,但不能确切地理解你的问题是什么。是的,这有点让人困惑。感觉这与有序特征有关,但不清楚是什么t你的目标是。为什么要使用
    对象
    而不是
    案例类
    ?@Luis Miguel Mejía Suárez感谢你的回答。我编辑了这个问题,让它更清楚我的问题到底是什么。我知道AB1和b是不同的类。但是我如何使用模式匹配来比较它们呢?@Andy Hayden,因为静态f我使用的函数和变量,我认为对象是正确的choice@SimonDose在case类+companion对象中,你不能两者兼得吗?
    trait B
    case class AB1(variable: Int) extends B
    
    implicit object AB1Ordering extends Ordering[AB1] {
      override def compare(o1: AB1, o2: AB1): Int = java.lang.Integer.compare(o1.variable, o2.variable)
    }
    val ab1List = List(AB1(1), AB1(2), AB1(3))
    val ab1ListSorted = ab1List.sorted
    
    trait B {}
    
    trait BComparator[Bi <: B] {
      def compare(firstB: Bi, secondB: Bi): Int
    }
    
    class B1 extends B {}
    object B1 {
      implicit val B1Comparator: BComparator[B1] = new BComparator[B1] {
        override def compare(firstB: B1, secondB: B2): Int = ???
      }
    }
    
    implicitly[BComparator[B1]].compare(b11, b12)