[英]Type class with default type parameter
我正在嘗試使用類型類解決表達式問題。 我的工作基於2013年Scala in Action的最新著作中的示例。
object StuffingSystem {
trait Stuffer[V, M, P] { def stuff(v: V, m: M, additionalparameters: List[P]): ... }
case class Input(v: BigDecimal) {
def stuff[M, P](m: M, additionalparameters: List[P])(implicit stuffer: Stuffer[Input, M, P]) = stuffer.stuff(v, m, additionalparameters)
}
case class Material(o: String)
}
object Stuffers {
import StuffingSystem._
implicit object InputStuffer extends Stuffer[Input, Material, Int] {
def stuff(v: Input, m: Material, p: List[Int]) = {
...
}
}
val stuffed = Input(BigDecimal(101.0)).stuff(Material("o"), List())
事實是我的stuff()
函數可以與其他Stuffer
一起使用一些其他參數。 如上例所示,當不需要時,我試圖得到的結果是不被迫提供一個空參數; 我希望能夠寫:
val stuffed = Input(BigDecimal(101.0)).stuff(Material(""))
val stuffedWithSomething = Input(BigDecimal(101.0)).stuff(Material(""), List("a", "b"))
我正在尋找一種優雅的方式來做到這一點。 我不太了解curring,但覺得這是解決方案的一部分。
這里是否可以使用默認類型參數? 還是有更好的方法?
您可以使用默認參數
object StuffingSystem {
trait Stuffer[V, M, P] {
def stuff(v: V, m: M, additionalparameters: List[P]): Unit
}
object Stuffer {
implicit def mkStuffer: Stuffer[Input, Material, String] = new Stuffer[Input, Material, String] {
override def stuff(v: Input, m: Material, additionalparameters: List[String]): Unit = ???
}
}
case class Input(v: BigDecimal) {
def stuff[M, P](m: M, additionalparameters: List[P] = List())(implicit stuffer: Stuffer[Input, M, P]) =
stuffer.stuff(Input(v), m, additionalparameters)
}
case class Material(o: String)
}
object Stuffers {
import StuffingSystem._
implicit object InputStuffer extends Stuffer[Input, Material, Int] {
def stuff(v: Input, m: Material, p: List[Int]) = ???
}
val stuffed = Input(BigDecimal(101.0)).stuff(Material("o"), List())
val stuffed1 = Input(BigDecimal(101.0)).stuff(Material(""))
val stuffedWithSomething = Input(BigDecimal(101.0)).stuff(Material(""), List("a", "b"))
}
或varargs
object StuffingSystem {
trait Stuffer[V, M, P] {
def stuff(v: V, m: M, additionalparameters: P*): Unit
}
object Stuffer {
implicit def mkStuffer: Stuffer[Input, Material, String] = new Stuffer[Input, Material, String] {
override def stuff(v: Input, m: Material, additionalparameters: String*): Unit = ???
}
}
case class Input(v: BigDecimal) {
def stuff[M, P](m: M, additionalparameters: P*)(implicit stuffer: Stuffer[Input, M, P]) =
stuffer.stuff(Input(v), m, additionalparameters:_*)
}
case class Material(o: String)
}
object Stuffers {
import StuffingSystem._
implicit object InputStuffer extends Stuffer[Input, Material, Int] {
def stuff(v: Input, m: Material, additionalparameters: Int*): Unit = ???
}
val stuffed = Input(BigDecimal(101.0)).stuff(Material("o"), Seq():_*)
val stuffed1 = Input(BigDecimal(101.0)).stuff(Material(""))
val stuffedWithSomething = Input(BigDecimal(101.0)).stuff(Material(""), Seq("a", "b"):_*)
val stuffedWithSomething1 = Input(BigDecimal(101.0)).stuff(Material(""), "a", "b")
}
為此,您不需要默認類型參數,只需一個普通的默認參數即可:
def stuff[M, P](m: M, additionalparameters: List[P] = Nil)(implicit stuffer: Stuffer[Input, M, P]) = ...
當然,如果您有多個具有不同P
Stuffer
,則會出現問題,但是您的原始情況已經存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.