简体   繁体   English

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

[英]Type class with default type parameter

I am trying to solve the expression problem using type classes. 我正在尝试使用类型类解决表达式问题。 I based my work on the example found in a late book of 2013 Scala in Action . 我的工作基于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())

The fact is that my stuff() function could use some additional parameters with other Stuffer s. 事实是我的stuff()函数可以与其他Stuffer一起使用一些其他参数。 The result I'm trying to get is not to be forced to give an empty parameter when none is required as shown in the example above ; 如上例所示,当不需要时,我试图得到的结果是不被迫提供一个空参数; I'd like to be able to write: 我希望能够写:

val stuffed = Input(BigDecimal(101.0)).stuff(Material(""))
val stuffedWithSomething = Input(BigDecimal(101.0)).stuff(Material(""), List("a", "b"))

I'm looking for an elegant way to do this. 我正在寻找一种优雅的方式来做到这一点。 I don't quite understand currying but feel like it'd part of the solution. 我不太了解curring,但觉得这是解决方案的一部分。

Is it possible to have default type parameter here? 这里是否可以使用默认类型参数? Or is there a better path? 还是有更好的方法?

You can use default parameter 您可以使用默认参数

  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"))
  }

or varargs 或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")
  }

For this you don't need default type parameters, just a normal default parameter: 为此,您不需要默认类型参数,只需一个普通的默认参数即可:

def stuff[M, P](m: M, additionalparameters: List[P] = Nil)(implicit stuffer: Stuffer[Input, M, P]) = ...

Of course there is a problem if you have multiple Stuffer s with different P , but there already is in your original situation. 当然,如果您有多个具有不同P Stuffer ,则会出现问题,但是您的原始情况已经存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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