繁体   English   中英

具有默认类型参数的类型类

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM