我试图实现一个函数,该函数需要另一个函数并将其应用到传递的列表上,而不是前一次调用的结果等等。 我想出了两个不同的函数签名,但是对于这两个编译器,它们都没有像我期望的那样派生类型参数,我现在想知道我是在搞砸事情还是在编译器。
object Repeater {
// The first parameter is passed in a separate parameter list.
def repeat[DstType >: ElemType, ElemType](list: List[ElemType])
(function: DstType => DstType,
times: Int): List[DstType] = {
var currentList: List[DstType] = list
for (_ <- 0 until times) {
currentList = currentList.map(function)
}
currentList
}
// The first parameter is passed in the same parameter list as the others.
def repeat2[DstType >: ElemType, ElemType](list: List[ElemType],
function: DstType => DstType,
times: Int): List[DstType] = {
var currentList: List[DstType] = list
for (_ <- 0 until times) {
currentList = currentList.map(function)
}
currentList
}
}
class Base()
class Extended() extends Base
object Test extends App {
val list: List[Extended] = Nil
Repeater.repeat(list)( x => x, 1)
Repeater.repeat(list)( (x: Base) => x, 1)
Repeater.repeat2(list, x => x, 1)
Repeater.repeat2(list, (x: Base) => x, 1)
}
对repeat()
的第一次调用会编译,我不需要在给repeat()
的函数中提供参数类型,这是我的预期行为。
对repeat()
的第二次调用无法编译:
Error:(25, 39) type mismatch;
found : pipeops.Base
required: pipeops.Extended
Repeater.repeat(list)( (x: Base) => x, 1)
我不理解此错误,因为找到的类型base
是Extended
的超级类型,因此适合我的提供类型绑定的DstType >: ElemTyp
。
对repeat2()
的第一次调用无法编译:
Error:(27, 26) missing parameter type
Repeater.repeat2(list, x => x, 1)
我发现在这种情况下编译器希望我指定功能参数类型真的很奇怪。
对repeat2()
的第二次调用确实已编译并且是有意的。
我现在有两个问题:
有人可以向我解释这些差异来自何处吗?
是否存在另一种指定重复函数的方法,如果所传递的函数从ElemType
到ElemType
,则不需要我指定参数类型,但允许我扩展所传递的函数如果需要,函数类型可用于ElemType
的超级类型。
答案 0 :(得分:1)
一种类型参数有什么问题?
object Repeater {
def repeat[ElemType](list: List[ElemType])
(function: ElemType => ElemType,
times: Int): List[ElemType] = {
var currentList: List[ElemType] = list
for (_ <- 0 until times) {
currentList = currentList.map(function)
}
currentList
}
def repeat2[ElemType](list: List[ElemType],
function: ElemType => ElemType,
times: Int): List[ElemType] = {
var currentList: List[ElemType] = list
for (_ <- 0 until times) {
currentList = currentList.map(function)
}
currentList
}
}
class Base()
class Extended() extends Base
object Test extends App {
val list: List[Extended] = Nil
val list1: List[Base] = list
Repeater.repeat(list)( (x: Extended) => x, 1)
Repeater.repeat(list1)( (x: Base) => x, 1)
Repeater.repeat2(list, (x: Extended) => x, 1)
Repeater.repeat2(list, (x: Base) => x, 1)
Repeater.repeat2(list1, (x: Base) => x, 1)
Repeater.repeat[Extended](list)( (x: Extended) => x, 1)
Repeater.repeat[Base](list1)( (x: Base) => x, 1)
Repeater.repeat2[Extended](list, (x: Extended) => x, 1)
Repeater.repeat2[Base](list, (x: Base) => x, 1)
}
如果有时候编译器没有让您明确指定类型,则意味着它可以自己推断类型,否则就不能,您应该指定。