假設,我有 2 個型別類:
trait Foo[A] {
...
}
trait Bar[A] {
...
}
然后我將他們的實體收集到集合中:
val seqFoo : Set[Foo[_]] = ...
val seqBar : Set[Bar[_]] = ...
有沒有辦法把這個序列組合成這樣的東西:
val fooBar = (Foo[Int],Bar[Int]), ... , (Foo[String],Bar[String])
也許模式匹配函式或型別標簽是一個答案,但我相信這個案例應該有更直接的解決方案
uj5u.com熱心網友回復:
例如,您可以使您的型別類抽象類而不是特征(然后它們可以有引數),添加隱式TypeTag引數,并groupBy為您的集合制作。
import scala.reflect.runtime.universe.{TypeTag, Type}
// type class
abstract class Foo[A](implicit val ttag: TypeTag[A]) {
def foo(): String // dummy method just to distinguish instances upon checking
}
// instances
object Foo1 {
implicit val intFoo: Foo[Int] = new Foo[Int]() {
override def foo(): String = "Foo1.intFoo"
}
implicit val strFoo: Foo[String] = new Foo[String]() {
override def foo(): String = "Foo1.strFoo"
}
}
object Foo2 {
implicit val intFoo: Foo[Int] = new Foo[Int]() {
override def foo(): String = "Foo2.intFoo"
}
implicit val boolFoo: Foo[Boolean] = new Foo[Boolean]() {
override def foo(): String = "Foo2.boolFoo"
}
}
object Foo3 {
implicit val intFoo: Foo[Int] = new Foo[Int]() {
override def foo(): String = "Foo3.intFoo"
}
implicit val strFoo: Foo[String] = new Foo[String]() {
override def foo(): String = "Foo3.strFoo"
}
implicit val boolFoo: Foo[Boolean] = new Foo[Boolean]() {
override def foo(): String = "Foo3.boolFoo"
}
}
val seqFoo : Set[Foo[_]] = Set(Foo1.intFoo, Foo1.strFoo, Foo2.intFoo, Foo2.boolFoo, Foo3.intFoo, Foo3.strFoo, Foo3.boolFoo)
val grouped: Map[Type, Set[Foo[_]]] = seqFoo.groupBy(_.ttag.tpe)
// checking that instances are grouped by type
grouped.view.mapValues(_.map(_.foo())).foreach(println)
//(Int,HashSet(Foo3.intFoo, Foo1.intFoo, Foo2.intFoo))
//(String,HashSet(Foo1.strFoo, Foo3.strFoo))
//(Boolean,HashSet(Foo2.boolFoo, Foo3.boolFoo))
同樣,您可以使用 andgroupBy為Bar然后做任何您想做的 Map[Type, Set[Foo[_]]]事情Map[Type, Set[Bar[_]]]。例如合并Maps
val grouped: Map[Type, Set[Foo[_]]] = ???
val grouped1: Map[Type, Set[Bar[_]]] = ???
val merged: Map[Type, (Set[Foo[_]], Set[Bar[_]])] =
(grouped.keySet union grouped1.keySet)
.map(tpe => tpe -> (grouped(tpe), grouped1(tpe)))
.toMap
我將從我的評論中復制。型別類的實體旨在由編譯器在編譯時自動決議(通過隱式決議)。手動收集實體似乎很奇怪,在運行時收集它們也是如此。
我的型別類實體實作解碼器/編碼器邏輯。它們還包含一些元資訊(特別是名稱)。所以我想根據有多少實體具有相同的名稱但不同的型別引數來檢查名稱到型別并生成唯一名稱。
盡管隱式名稱有時會影響隱式決議(1 2 3 4),但通常您不應該對隱式名稱或名稱與型別的對應關系感興趣。也許您應該提供一些代碼片段,以便我們了解您的設定和目標。也許您需要的可以在編譯時和/或自動完成。
或者,如果您更喜歡保留型別類特征或者您不能修改它們的代碼,您可以使用磁鐵模式(1 2 3 4 5 6 7 8)
trait Foo[A] {
def foo(): String
}
implicit class Magnet[F[_], A: TypeTag](val inst: F[A]) {
def tpe: Type = typeOf[A]
}
val seqFoo = Set[Magnet[Foo, _]](Foo1.intFoo, Foo1.strFoo, Foo2.intFoo, Foo2.boolFoo, Foo3.intFoo, Foo3.strFoo, Foo3.boolFoo)
val grouped: Map[Type, Set[Magnet[Foo, _]]] = seqFoo.groupBy(_.tpe)
// checking that instances are grouped by type
grouped.view.mapValues(_.map(_.inst.foo())).foreach(println)
//(String,HashSet(Foo1.strFoo, Foo3.strFoo))
//(Int,HashSet(Foo3.intFoo, Foo1.intFoo, Foo2.intFoo))
//(Boolean,HashSet(Foo2.boolFoo, Foo3.boolFoo))
使用“Prolog in Scala”查找可用的型別類實體
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/522464.html
標籤:斯卡拉收藏品类型类
上一篇:什么是錯誤“未找到:鍵入分數”?
