Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的泛型类型推理_Scala_Generics_Type Inference - Fatal编程技术网

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

我编写了以下代码,这实际上是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) 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创建了一个。