Scala匿名函数genric方差问题 [英] Scala anonymous function genric variance issues

查看:144
本文介绍了Scala匿名函数genric方差问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Scala,我很难理解反向变量,协变量,不变性等。从为什么这个例子没有编译,又如何(合作,反对和in)差异工作?我已经学会了如何将函数视为另一个函数的子类型。 (真的很有用!)



下面的代码是我认为解决我的难题的重要部分。我提取了一些我认为会给问题增加不必要的复杂性的部分。根据示例,我有一个Student对象,它将充当工厂来生成函数。

函数将采用AnyVal的类型或子类型(Int,Double,Long等),并且返回输出将具有相同的输入类型。为了达到这个目的,学生类接受一个通用的(A),它是AnyVal的一个子类型。抽象类在那里,以便我可以通过执行List [Master [AnyVal]](Student.func1)等方式来引用这些学生的列表。



问题是我不能有行val函数:List [A] => A因为我得到错误协变类型A发生在类型的逆变位置=>列表[A] =>值函数的一个。我不知道为什么返回类型必须是A的逆变。我可以根据Function1的特性来接受这个名称。

那么我如何在抽象主类中定义我的函数,以便返回类型是类型A的逆变?我找到了一个如何用函数定义(例如def函数[B>:A](v:B):List [B])来定义这个函数的例子,但是我怎么用一个匿名函数来实现呢?记住主抽象类中的A必须是协变的,因为会有一个接受所有AnyVal类型(Int,Double等)的函数列表。

真的感谢帮助!让我知道我的任何术语是否关闭。 - Scala Learner

 抽象类Master [+ A] {
val函数:List [A] => A
}

class Student [A< ;:AnyVal](val函数:List [A] => A)扩展Master [A]

object学生{
def func1 =
new Student((params:List [Int])=> params(0)+ params(1))
}

val myFunc = Student.func1 $ b $ val someList = List [Master [AnyVal]](myFunc)


解决方案

使用协变类型创建泛型类或特征是非常困难的。一旦添加了方差注释,就不能将该类型用作任何类方法的参数。这是因为函数在它们的参数中是对立的,在它们的返回类型中是协变的。在 接受的答案中有一个非常好的解释。



如果你真的希望类型是协变的,你必须编写所有的方法来获取类型为[B>:A]的参数 - 也就是说,把A的超类作为它们的参数类型。这可能相当具有挑战性;在线Scala文档有可能需要的杂技示例


I'm on the road to learn Scala and I'm having a hard time understanding contravariants, covariants, invariance, etc. From Why doesn't the example compile, aka how does (co-, contra-, and in-) variance work? I have learned how functions can be considered subtypes of another function. (Really useful to know!)

The code below is what I believe are the important pieces to solving my puzzle. I have extracted parts that I think would add unneeded complexity to the problem. According to the example I have a Student object that will act as a factory to generate functions.

Functions will take in types or subtyes of AnyVal (Int, Double, Long, etc.), and the return output will be of the same input type. To achieve this the student class takes in a generic (A) that is a subtype of AnyVal. The abstract class is there so that I can refer a list of these students by doing something like List[Master[AnyVal]]( Student.func1).

The problem is that I cannot have the line "val function: List[A] => A" as I get error "covariant type A occurs in contravariant position in type => List[A] => A of value function". I don't know why the return type must be the contravariant of A. I can somewhat accept this fact for name based on the Function1 trait.

So how would I define my function in the abstract Master class so that the return type is a contravariant of type A? I found an example of how to define this with function definitions (Ex. def function[B >: A](v: B): List[B]), but how would I implement this with an anonymous function? Remember "A" in the master abstract class must be covariant since there will be a list of function that take in all AnyVal types (Int, Double, etc.)

Really appreciate the help! Let me know if any of my terminology is off. - Scala Learner

abstract class Master[+A] {
    val function: List[A] => A
}

class Student[A <: AnyVal](val function: List[A] => A) extends Master[A]

object Student {
def func1 =
    new Student((params: List[Int])=>params(0) + params(1))
}

val myFunc = Student.func1
val someList = List[Master[AnyVal]](myFunc)

解决方案

It is very difficult to create generic classes or traits parameterised with a covariant type. Once you add the variance annotation, you cannot use the type as a parameter for any of the class methods. This is because functions are contra-variant in their parameters and covariant in their return types. There is a very good explanation in this accepted answer.

If you really want the type to be covariant, you have to write all the methods to take parameters of type [B >: A] - that is, to take supertypes of A as their parameter type. This can be quite challenging; the online Scala documentation has an example of the acrobatics that might be required.

这篇关于Scala匿名函数genric方差问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆