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