比较器是类型类吗? [英] Is Comparator a type class?

查看:182
本文介绍了比较器是类型类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读Scala中的类型类,并认为我对它有很好的把握,直到我记得Java的 java.util.Comparator

I've been reading up on type classes in Scala and thought I had a good grasp on it, until I remembered Java's java.util.Comparator.

如果我理解正确,订购是类型类的典型示例。我能想到的 Comparator Ordering 的实例之间的唯一区别是,比较器必须是显式的,而排序可以,而且经常是隐含的。

If I understand properly, Ordering is the prototypical example of a type class. The only difference I can think of between a Comparator and an instance of Ordering is that comparators are necessarily explicit, while orderings can be, and often are, implicit.

比较器类型类?我得到(错误的?)印象,Java实际上没有类型类。这是否意味着类型类需要能够隐式?我认为类型类的隐式转换主要是语法糖 - 实际上很棒,它简单地给编译器足够的提示 - 我错过了什么?

Is Comparator a type class? I get the (mistaken?) impression that Java does not actually have type classes. Does this mean that a type class needs to be able to be implicit? I considered implicit conversions of type classes to be mostly syntactic sugar - awesome as it is, it's "simply" giving the compiler enough hint - was I missing something?

以下代码示例显示 Comparator 如何将排序操作添加到没有它的类型,而不必修改所述类型。

The following code example shows how Comparator adds an ordering operation to a type that didn't have it, without having to modify said type.

// Comparator used to retroactively fit the MyExample class with an ordering operation.
public static class MyExampleComparator implements Comparator<MyExample> {
    public static final Comparator<MyExample> SINGLETON = new MyExampleComparator();

    private MyExampleComparator() {}

    public int compare(MyExample a, MyExample b) {
        return a.value - b.value;
    }
}

// Custom type, its only purpose is to show that Comparator can add an ordering operation to it when it doesn't
// have one to begin with.
public static class MyExample {
    private final int value;

    public MyExample(int v) {
        value = v;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

public static void main(String... args) {
    List<MyExample> list = new ArrayList<MyExample>();

    for(int i = 0; i < 10; i++)
        list.add(new MyExample(-i));

    // Sorts the list without having had to modify MyExample to implement an interface.
    Collections.sort(list, MyExampleComparator.SINGLETON);

    // Prints the expected [-9, -8, -7, -6, -5, -4, -3, -2, -1, 0]
    System.out.println(list);
}


推荐答案

我不想特别说话关于类型类,但关于Scala中的类型类模式;原因是,当你开始询问什么是类型类时,你最终得出的结论是它只是一个以特定方式使用的接口。

I prefer not to talk specifically about type classes but about the type class pattern in Scala; the reason is that when you start asking "what is the type class", you end up concluding that it is just an interface used in a particular way.

(在Haskell中) 将特定构造称为类型类更有意义。)

(In Haskell it makes more sense to call a specific construct a type class.)

类型类模式由三个基本部分组成(但为方便起见,通常还有一些部分)。第一种是由单一类型参数化的接口,它在参数化类型上抽象出某种能力。 java.util.Comparator 是一个很好的例子:它提供了一个比较接口。让我们使用它。

The type class pattern consists of three essential parts (but there are usually a couple more for convenience). The first is an interface parameterized by a single type that abstracts some sort of capability on the parameterized type. java.util.Comparator is a perfect example: it provides an interface for comparison. Let's just use that.

您需要的第二件事是使用该参数化的方法,您可以在Scala中使用简写符号指定:

The second thing you need is a method that makes use of that parameterization, which you can specify with short-hand notation in Scala:

// Short signature
//             v------------------- "We must be able to find a Comparator for A"
def ordered[A: java.util.Comparator](a0: A, a1: A, a2: A) = {
  val cmp = implicitly[java.util.Comparator[A]]   // This is the Comparator
  cmp.compare(a0, a1) <= 0 && cmp.compare(a1, a2) <= 0
}

// Long signature version
def ordered[A](a0: A, a1: A, a2: A)(implicit cmp: java.util.Comparator[A]) = {
  cmp.compare(a0, a1) <= 0 && cmp.compare(a1, a2) <= 0
}

好的,但是哪里你从那个比较器?这是第三个必要的部分。默认情况下,Scala不会为您可能喜欢的课程提供比较器,但您可以定义自己的类:

Okay, but where do you get that comparator from? That's the third necessary piece. By default, Scala doesn't give you Comparators for the classes you might like, but you can define your own:

implicit object IntComp extends java.util.Comparator[Int] {
  def compare(a: Int, b: Int) = a.compareTo(b)
}

scala> ordered(1,2,3)
res5: Boolean = true

scala> ordered(1,3,2)
res6: Boolean = false

现在你' ve提供了 Int (隐式)的功能,编译器会将隐式参数填入 ordered 以使其工作。如果您尚未提供该功能,则会出错:

Now that you've provided the functionality for Int (implicitly), the compiler will fill in the implicit parameter to ordered to make it work. If you haven't yet provided the functionality, it gives an error:

scala> ordered("fish","wish","dish")
<console>:12: error: could not find implicit value
for parameter cmp: java.util.Comparator[String]
          ordered("fish","wish","dish")

直到您提供该功能:

implicit object StringComp extends java.util.Comparator[String] {
  def compare(a: String, b: String) = a.compareTo(b)
}

scala> ordered("fish","wish","dish")
res11: Boolean = false



<那么,我们调用 java.util.Comparator 类型类吗?它当然与处理类型类模式的等效部分的Scala特征一样起作用。因此,即使类型类模式在Java中也不起作用(因为您必须显式指定要使用的实例而不是隐式查找它),从Scala透视图 java.util.Comparator 与任何类型都是类型类。

So, do we call java.util.Comparator a type class? It certainly functions just as well as a Scala trait that handles the equivalent part of the type class pattern. So even though the type class pattern doesn't work as well in Java (since you have to explicitly specify the instance to use instead of having it implicitly looked up), from a Scala perspective java.util.Comparator is as much a type class as anything.

这篇关于比较器是类型类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆