簡體   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