我正在尝试使用类型类解决表达式问题。我的工作基于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,但觉得它是解决方案的一部分。
这里是否可以使用默认类型参数?还是有更好的方法?
答案 0 :(得分:1)
您可以使用默认参数
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")
}
答案 1 :(得分:0)
为此,您不需要默认的 type 参数,只需一个常规的默认参数:
def stuff[M, P](m: M, additionalparameters: List[P] = Nil)(implicit stuffer: Stuffer[Input, M, P]) = ...
如果您有多个Stuffer
不同的P
,当然会出现问题。