[英]Is it possible for Scala to infer types for Generic types passed into a dependent class?
鑒於以下情況:
trait A[X] {
def foo(): X
}
class B[T <: A[_]] {
def getFoo(a:T) = a.foo()
}
class C[T <: A[Z], Z] {
def getFoo(a:T):Z = a.foo()
}
是否可以讓 B 像 C 一樣工作? 具體獲取a.foo()的結果類型。
scala> var b:B[A[Int]] = new B[A[Int]]()
scala> b.getFoo(AA(1))
res0: Any = 1
scala> var c:C[A[Int],Int] = new C[A[Int],Int]()
c: C[A[Int],Int] = C@4cc36c19
scala> c.getFoo(AA(1))
res1: Int = 1
b 返回 Any,但 c 正確返回 Int。 這顯然是一個人為的例子,但如果我可以從泛型類型中提取子類型,它會大大簡化代碼。 基本上,知道“Z”(在 C 中使用)而不必顯式傳遞它 - 從 A 的類型推斷。
顯然,C 根據需要工作,但問題是我的框架更類似於:
class D[T <: A[Z1], U <: B[Z2], Z1, Z2] extends E[T,U,Z1,Z2]
然后需要框架的用戶使用 4 個類型參數來實現,理想情況下它只有 2 個
class D[T <: A[_], U <: B[_]] extends E[T,U]
不是阻止程序,只是嘗試簡化公開的 API。
您可以執行以下在某些基於類型類的庫中經常使用的操作:
trait Foo[H[_] <: Langh[_]]{
def thing[A](ha: H[A]): A = ha.ha()
}
這將類型參數的解析推送到方法thing
的調用。 它使用更高級的類型。
事實上,如果你看看像ScalaZ這樣的庫,你會看到這個模式:
trait Functor[F[_]]{
def map[A, B](fa: F[A])(f: A => B): F[B]
}
回復評論
沒有辦法讓U <: T[_]
類型然后能夠提取出實際T[A]
的類型參數,因為它的定義本身就丟失了這些信息。 如果以上對您不起作用,那么我建議類型類:
trait Foo[U]{
def doStuff(u: U)(implicit ev: MyTypeClass[U]): ev.A = //...
}
其中您只定義您的MyTypeClass
隱式,如下所示:
trait Whatever[FA]{ /*...*/ }
object Whatever{
implicit def WhateverMTC[F[_] <: Bound[_], A0] = new MyTypeClass[F[A0]]{
type A = A0
//...
}
}
然后你可以將你的類型綁定在隱式上,你的隱式帶有你的類型必須是高級類型的約束,你可以得到一個方法,在調用站點聲明中返回內部“隱藏”類型。
也就是說,當第一個建議更加優雅和更簡潔的方法來解決問題恕我直言時,這是很多機器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.