簡體   English   中英

Scala 是否可以推斷傳遞給依賴類的泛型類型的類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM