Scala通用推理

时间:2018-09-18 15:08:47

标签: scala generics

我希望对具有s后代的对象序列A的类进行自动类型推断,因为知道A采用通用参数。

class A[F](val field1: F)

class G[F, Aa <: A[F], S <: Seq[Aa]](val s: S) {
  // what i have to do
}

// Evrything is ok
val gWith = new G[Int, A[Int], List[A[Int]]](List(new A(5)))

// Compilator failed: inferred type arguments [Nothing,Nothing,List[A[Int]]]
val gWithout = new G(List(new A(5)))

我要补充一点,我明确需要知道AaS类型以便以后重用。

是否有任何解决方案可分配用户以放置这些泛型类型。如果没有,我会很高兴知道为什么。

2 个答案:

答案 0 :(得分:2)

您可以简化G类的类型参数:

class A[F](val field1: F)

class B[F](override val field1: F) extends A[F](field1)

// Make A covariant
class G[F, S[+A] <: Seq[A]](val s: S[A[F]]) { }

// Everything is ok
val gWith = new G[Int, List](List(new A(5)))

// Also ok
val gWithout = new G(List(new A(5)))

// Ok too
val gBWithout = new G(List(new B(5)))

工作中的顽固主义者:https://scastie.scala-lang.org/fmOLxCiKRBKIDFSj7stZNQ

答案 1 :(得分:2)

您可以通过类型约束来实现所需的目标

class A[F](val field1: F)

class G[F, Aa, S](val s: S)(implicit ev2: S <:< Seq[Aa], ev1: Aa <:< A[F]) {}

val gWithout = new G(List(new A(5))) // gWithout: G[Int,A[Int],List[A[Int]]] = G@79d7035

我真的无法解释为什么以前不起作用以及为什么现在不能起作用,但是我可以告诉你它与类型推断有关,我一直在RELP中使用您的代码段播放 (使用'-explaintypes'标志),我总是发现一些奇怪的错误,例如:

  

什么都没有::列表[A [Int]]?

     

true

     

什么都没有::什么?

     

true

     

什么都没有:: [没有]?

     

true

     

List [A [Int]] <:Seq [Nothing]?

     

false

     

错误:推断出的类型参数[Nothing,Nothing,List [A [Int]]]不符合类G的类型参数范围[F,Aa <:A [F],S <:Seq [Aa]] < / p>      

val gWithout = new G(List(new A(5)))

     

列表[A [Int]] <:S?   错误

我发现this post,但我还没有完全读完它,但是似乎有一个更好的解释说明为什么现在可以使用它。