Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 从高阶函数构建通用的可重用迭代模块_Scala_Oop_Generics_Functional Programming_Higher Order Functions - Fatal编程技术网

Scala 从高阶函数构建通用的可重用迭代模块

Scala 从高阶函数构建通用的可重用迭代模块,scala,oop,generics,functional-programming,higher-order-functions,Scala,Oop,Generics,Functional Programming,Higher Order Functions,如何为迭代创建一个可重用的模块,使我能够: 选择它是否并行迭代 让我指定需要执行哪些任务的高阶函数 下面是一些虚拟函数。它们本身就构成了问题的第二部分: 我是否应该在这里有一个接口,使这些函数中的每个函数至少实现参数inputDay:String? 或者最好是使用配置类的泛型函数,其中配置实现了一个最小的接口 def doStuff(inputDay: String, inputConfigSomething: String): Unit = println(inputDay + input

如何为迭代创建一个可重用的模块,使我能够:

  • 选择它是否并行迭代
  • 让我指定需要执行哪些任务的高阶函数
下面是一些虚拟函数。它们本身就构成了问题的第二部分: 我是否应该在这里有一个接口,使这些函数中的每个函数至少实现参数
inputDay:String
? 或者最好是使用配置类的泛型函数,其中配置实现了一个最小的接口

def doStuff(inputDay: String, inputConfigSomething: String): Unit = println(inputDay + inputConfigSomething)
def doOtherStuff(inputDay: String): Unit = println(inputDay)
下面是迭代模块的一个示例,首先是所执行任务的具体实现:

val days = Seq("20190101", "20190102", "20190103")
val something = "foo"

def iteration(d: Seq[String], parallel: Boolean = false) = {
  if (parallel) {
    d.par.foreach(dd => {
      println(dd)
    })
  } else {
    d.foreach(dd => {
      println(dd)
    })
  }
}

iteration(days)
第二,高阶函数应该可以用来控制计算的内容,而不是具体的实现。 不幸的是,下面的代码尚未编译

def iterationModule(d: Seq[String], functionToApply: Function, parallel: Boolean = false) = {
  if (parallel) {
    d.par.foreach(dd => {
      functionToApply(dd)
    })
  } else {
    d.foreach(dd => {
      functionToApply(dd)
    })
  }
}

iterationModule(days, doStuff)
请使用更通用的实现重试。这似乎太复杂了。一定有更简单的方法。也, 它仍然无法编译,因为我无法在迭代模块中动态实例化C。而且,一次又一次地输入一些Cs和Fs是相当烦人的

trait MinimalIterationParameters {
  def inputDay: String
}

trait FunctionParameters

trait OperationService[C <: MinimalIterationParameters, F <: FunctionParameters] {
  def doOperation(config: C, functionParameter: F): Unit
}

case class Minimal(override val inputDay: String) extends MinimalIterationParameters

case class ExtendedThing(inputConfigSomething: String) extends FunctionParameters

object MyDummyOperationService extends OperationService[Minimal, ExtendedThing] {
  override def doOperation(config: Minimal, functionParameter: ExtendedThing): Unit = {
    println(config.inputDay + functionParameter.inputConfigSomething)
  }
}

def iterationModuleGeneric[C <: MinimalIterationParameters, F <: FunctionParameters](d: Seq[String], functionToApply: OperationService[C, F], f: F, parallel: Boolean = false) = {
  if (parallel) {
    d.par.foreach(dd => {
      functionToApply.doOperation(C(dd), f)
    })
  } else {
    d.foreach(dd => {
      functionToApply.doOperation(C(dd), f)
    })
  }
}

val c = Minimal
iterationModuleGeneric[Minimal, ExtendedThing](days, MyDummyOperationService, f = ExtendedThing("foo"))
然而:

iterationModule[String](days, doStuff(d_each_reference, "foo"))
显然不会编译为
d\u每个参考
都没有定义。如何访问当前迭代项并将其传递给函数

此外,尝试传递迭代项和配置的展开视图:

val configForIteration = days.map(d=> (d, something))
iterationModule[(String, String)](configForIteration, doStuff)

不会编译。

这是否更接近您的目标

def iterationModule(d: Seq[String], functionToApply: Function, parallel: Boolean = false) = {
  if (parallel) {
    d.par.foreach(dd => {
      functionToApply(dd)
    })
  } else {
    d.foreach(dd => {
      functionToApply(dd)
    })
  }
}

iterationModule(days, doStuff)
def iterationModule[A](d: Seq[A], functionToApply: A=>Any, parallel: Boolean = false) :Unit =
  if (parallel) d.par.foreach(functionToApply)
  else          d.foreach(functionToApply)

def doStuff(a:Char, b :String) :Unit = println(a+b)
iterationModule(List('X','Y','Z'), doStuff(_, "foo"))
//Xfoo
//Yfoo
//Zfoo

令人惊叹的。但是我需要能够读取函数中当前的迭代项。这怎么可能?请查看更新的问题。这就是完成工作的原因。我不明白投反对票的原因。也许存在更好的解决方案?更好的解决方案?可能总有一个“更好”的解决方案。至于反对票:我似乎被列入了某人的黑名单。免责声明:我不是反对票(我甚至刚刚投了赞成票)使用
Traversable
IterableOnce
(在2.13中)使其更通用怎么样?