Тип класса с параметром типа по умолчанию - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь решить проблему выражения, используя классы типов.Я основал свою работу на примере, найденном в поздней книге 2013 года Scala в действии .

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 s.Результат, который я пытаюсь получить, не заставляет давать пустой параметр, когда ни один не требуется, как показано в примере выше;Я хотел бы иметь возможность написать:

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

Я ищу элегантный способ сделать это.Я не совсем понимаю карри, но чувствую, что это часть решения.

Возможно ли иметь здесь параметр типа по умолчанию?Или есть лучший путь?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Вы можете использовать параметр по умолчанию

  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")
  }
0 голосов
/ 25 октября 2018

Для этого вам не нужны параметры по умолчанию type , просто обычный параметр по умолчанию:

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

Конечно, существует проблема, если у вас есть несколько Stuffer сотличается P, но в исходной ситуации уже есть.

...