无法定义类型类

时间:2016-08-10 09:08:38

标签: scala typeclass

我正在尝试创建一个类型类,它将排序合并功能添加到列表中。

trait SortedMerge[A, B[A] <: List[A]] {
  def sortedMerge(l1: B[A], l2: B[A]): B[A]
}

implicit val IntSortedMerge = new SortedMerge[Int, List[Int]] {
  override def sortedMerge(l1: List[Int], l2: List[Int]): List[Int] = {
    @tailrec
    def merge(l1: List[Int], l2: List[Int], l: List[Int]): List[Int] = {
      (l1, l2) match {
        case (Nil, Nil) => l
        case (Nil, _) => l ++ l2
        case (_, Nil) => l ++ l1
        case (h1 :: t1, h2 :: t2) if (h1 < h2) => merge(t1, l2, l :+ h1)
        case (h1 :: t1, h2 :: t2) => merge(l1, t2, l :+ h2)
      }
    }

    merge(l1, l2, List[Int]())
  }
}


def sortedMerge[A, List[A]](l1: List[A], l2: List[A])
  (implicit merger: SortedMerge[A, List[A]]) = merger.sortedMerge(l1, l2)

我收到以下错误,

error: List[Int] takes no type parameters, expected: one
   val IntSortedMerge = new SortedMerge[Int, List[Int]] {
                                             ^

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

您收到此错误的原因是由于此绑定[A, B[A] <: List[A]]。第二类参数应该是更高级的类型。所以你的代码会以这种方式被重写

import scala.language.higherKinds

val IntSortedMerge = new SortedMerge[Int, List] {
  // stuff
}

def sortedMerge[A](l1: List[A], l2: List[A])
  (implicit merger: SortedMerge[A, List]) = merger.sortedMerge(l1, l2)

修改

在您的情况下,您实际上可以删除第二个类型参数,因为您期望(?)仅列出:

trait SortedMerge[A] {
  def sortedMerge(l1: List[A], l2: List[A]): List[A]
}

val IntSortedMerge = new SortedMerge[Int] {
  // stuff
}

def sortedMerge[A](l1: List[A], l2: List[A])
  (implicit merger: SortedMerge[A]) = merger.sortedMerge(l1, l2)

但是你也可以削弱像[A, B[A] <: Seq[A]]之类的绑定,它允许你为任何Seq子类构建SortedMerge。

答案 1 :(得分:1)

这编译好:

trait SortedMerge[A, B <: List[A]] {
  def sortedMerge(l1: B, l2: B): B
}

implicit val IntSortedMerge = new SortedMerge[Int, List[Int]] {
    // ... omitted
}

def sortedMerge[A, B <: List[A]](l1: B, l2: B)
    (implicit merger: SortedMerge[A, B]) = merger.sortedMerge(l1, l2)    

使用方法:

println(sortedMerge[Int, List[Int]](List(2, 4), List(1, 3)))

打印:

List(1, 2, 3, 4)