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中)使其更通用怎么样?