scala类型参数化混淆

scala类型参数化混淆,scala,parameterization,Scala,Parameterization,考虑下面的例子 abstract class Lookup(val code:String,val description:String) class USState(code:String, description:String, val area:Symbol) extends Lookup(code,description) class Country(code:String, description:String, val postCode:String) extends L

考虑下面的例子

abstract class Lookup(val code:String,val description:String)

class USState(code:String, description:String, val area:Symbol)
  extends Lookup(code,description)

class Country(code:String, description:String, val postCode:String)
  extends Lookup(code,description)

class HtmlLookupSelect(data:List[Lookup]) {
  def render( valueMaker:(Lookup) => String ) =
    data.map( (l) => valueMaker(l) )
}

val countries = List(
  new Country("US","United States","USA"),
  new Country("UK","Unites Kingdom","UK"),
  new Country("CA","Canada","CAN"))

def lookupValue(l:Lookup) = l.description
def countryValue(c:Country) = c.description + "(" + c.postCode + ")"

val selector = new HtmlLookupSelect(countries) //Doesn't throw an error
selector.render(countryValue) //Throws an error
htmlookupselect
需要一个查找对象列表作为构造函数参数。创建HtmlLookupSelect对象时,会向其传递一个county对象列表,编译器不会抛出错误,因为它将
国家
识别为
查找
的子类


但是在下一行中,当我尝试调用一个以Country作为参数类型的方法(而不是预期的查找)时,我得到了一个
类型不匹配
错误。为什么会这样

countryValue
是一个从
Country
String
的函数(实际上是一个将eta扩展为函数的方法,但现在不相关),即
Function1[国家,字符串]

render
需要一个
函数1[查找,字符串]

所以我们要回答的问题是

给定的
Country
Lookup

Function1[Country,String]
Function1[Lookup,String]
的子类型吗

为了回答这个问题,让我们看看
Function1
的定义:

trait Function1[-T1, +R] extends AnyRef
参见
-T1
?这是输入参数,
-
表示
函数1
在其输入参数中为逆变,在其输出参数中为协变


因此,如果
A
countryValue
是一个从
Country
String
的函数(实际上是一个将eta扩展为函数的方法,但现在不相关),即
Function1[Country,String]

render
需要一个
函数1[查找,字符串]

所以我们要回答的问题是

给定的
Country
Lookup

Function1[Country,String]
Function1[Lookup,String]
的子类型吗

为了回答这个问题,让我们看看
Function1
的定义:

trait Function1[-T1, +R] extends AnyRef
参见
-T1
?这是输入参数,
-
表示
函数1
在其输入参数中为逆变,在其输出参数中为协变


因此,如果
A
countryValue
是一个从
Country
String
的函数(实际上是一个将eta扩展为函数的方法,但现在不相关),即
Function1[Country,String]

render
需要一个
函数1[查找,字符串]

所以我们要回答的问题是

给定的
Country
Lookup

Function1[Country,String]
Function1[Lookup,String]
的子类型吗

为了回答这个问题,让我们看看
Function1
的定义:

trait Function1[-T1, +R] extends AnyRef
参见
-T1
?这是输入参数,
-
表示
函数1
在其输入参数中为逆变,在其输出参数中为协变


因此,如果
A
countryValue
是一个从
Country
String
的函数(实际上是一个将eta扩展为函数的方法,但现在不相关),即
Function1[Country,String]

render
需要一个
函数1[查找,字符串]

所以我们要回答的问题是

给定的
Country
Lookup

Function1[Country,String]
Function1[Lookup,String]
的子类型吗

为了回答这个问题,让我们看看
Function1
的定义:

trait Function1[-T1, +R] extends AnyRef
参见
-T1
?这是输入参数,
-
表示
函数1
在其输入参数中为逆变,在其输出参数中为协变

因此,如果
A