Scala中的泛型类型推理
我编写了以下代码,这实际上是scala中的一个哑合并排序实现:Scala中的泛型类型推理,scala,generics,type-inference,Scala,Generics,Type Inference,我编写了以下代码,这实际上是scala中的一个哑合并排序实现: import scala.collection.immutable.List object MergeSort { def sort[T,E]( comparator: (E,E) => Int ) (l: List[T]): List[T] = { def merge[T](first: List[T], second: List[T]): List[T] = (first, second) mat
import scala.collection.immutable.List
object MergeSort {
def sort[T,E]( comparator: (E,E) => Int ) (l: List[T]): List[T] = {
def merge[T](first: List[T], second: List[T]): List[T] = (first, second) match {
case (_, List()) => first
case (List(), _) => second
case (f::restFirst, s::restSecond) if comparator(f.asInstanceOf[E],s.asInstanceOf[E]) < 0 => f :: merge(restFirst, second)
case (f::restFirst, s::restSecond) => s :: merge(first, restSecond)
}
l match {
case List() => return l
case List(x) => return l
case _ => {
val (first, second) = l.splitAt( l.length / 2 )
merge( sort(comparator)(first), sort(comparator)(second) )
}
}
}
}
导入scala.collection.immutable.List
对象合并排序{
定义排序[T,E](比较器:(E,E)=>Int)(l:List[T]):List[T]={
def merge[T](第一:列表[T],第二:列表[T]):列表[T]=(第一,第二)匹配{
case(u,List())=>第一个
大小写(列表(),)=>秒
如果比较器(f.asInstanceOf[E],s.asInstanceOf[E])<0=>f::merge(restFirst,second),则为case(f::restFirst,s::restsond)
case(f::restFirst,s::restsond)=>s::merge(first,restsond)
}
我匹配{
案例列表()=>返回l
案例列表(x)=>返回l
案例=>{
val(第一,第二)=l.splitAt(l.length/2)
合并(排序(比较器)(第一)、排序(比较器)(第二))
}
}
}
}
这不是以下更优雅的解决方案:
import scala.collection.immutable.List
object MergeSort {
def sort[T]( comparator: (T,T) => Int ) (l: List[T]): List[T] = {
def merge[T](first: List[T], second: List[T]): List[T] = (first, second) match {
case (_, List()) => first
case (List(), _) => second
case (f::restFirst, s::restSecond) if comparator(f,s) < 0 => f :: merge(restFirst, second)
case (f::restFirst, s::restSecond) => s :: merge(first, restSecond)
}
l match {
case List() => return l
case List(x) => return l
case _ => {
val (first, second) = l.splitAt( l.length / 2 )
merge( sort(comparator)(first), sort(comparator)(second) )
}
}
}
}
导入scala.collection.immutable.List
对象合并排序{
def sort[T](比较器:(T,T)=>Int)(l:List[T]):List[T]={
def merge[T](第一:列表[T],第二:列表[T]):列表[T]=(第一,第二)匹配{
case(u,List())=>第一个
大小写(列表(),)=>秒
如果比较器(f,s)<0=>f::merge(restFirst,second),则使用case(f::restFirst,s::restsond)
case(f::restFirst,s::restsond)=>s::merge(first,restsond)
}
我匹配{
案例列表()=>返回l
案例列表(x)=>返回l
案例=>{
val(第一,第二)=l.splitAt(l.length/2)
合并(排序(比较器)(第一)、排序(比较器)(第二))
}
}
}
}
无法编译,给我以下错误消息:
MergeSort.scala:10: type mismatch;
[error] found : f.type (with underlying type T)
[error] required: T
[error] case (f::restFirst, s::restSecond) if comparator(f,s) < 0 => f :: merge(restFirst, second)
MergeSort.scala:10:类型不匹配;
找到[错误]:f.type(具有基础类型T)
[错误]必需:T
如果比较器(f,s)<0=>f::merge(restFirst,second),则使用[error]case(f::restFirst,s::restsond)
既然底层类型是T,为什么需要显式强制转换?这是我能想到的最烦人的Scala问题之一(可能是在与运算符有关的分号推理问题之后)。你离正确答案还有三个字符 问题是
merge
上的类型参数。它引入了一个新的T
,将T
类型参数隐藏在sort
上。因此,编译器不知道comparator
可以应用于新t
的实例。你可以用演员阵容来控制它,这就是为什么你的第一个版本可以工作的原因,但除此之外,它将T
视为一张白板
只需编写
def merge(第一个:List[T],…
,您就可以了。隐藏本地类型参数应该可以用实现。我将尝试创建一个规则。对于类型参数,从不同文件隐藏类型,这是IDE的事情,我为Scala IDE创建了一个。