Scala动态构建的可变输入函数链

aiazj4mn  于 2023-02-08  发布在  Scala
关注(0)|答案(1)|浏览(149)

我正在尝试动态创建一个函数链来对一个数值执行操作。这个函数链是在运行时从文本指令创建的。诀窍在于函数的类型不同。有些函数生成Double,有些生成Long。

    • 更新**

核心问题是我有大量的数据要处理,但是不同的值需要不同的处理。除了数据之外,我还有关于如何提取值并将其操作为最终形式的规范,例如应用多项式、使用查找表、更改二进制格式(如2s Complement)等。这些规范在某种文件中(我从数据库创建文件,但这对对话并不重要),我可以将这些规范应用于多个数据文件。
函数也是如此(这些只是例子;有成吨的):

def Multiply(input: Long, factor:Double):Double = input*factor
  def Poly(input:Double, co:Array[Double]):Double = // do some polynomial math

我可以手动创建这样的链:

val poly = (x: Double) => EUSteps.Poly(x,Array[Double](1,2))
val mult = (x: Long) => EUSteps.Multiply(x, 1.5)
val chain = mult andThen poly

如果我调用chain(1)得到4
现在我希望能够解析一个字符串,比如"MULT(1.5);POLY(1,2)"并得到相同的链。这个想法是我可以定义链,我想。也许它的" MULT(1.5);MULT(2); POLY(1,2,3)",所以我可以让函数通用,如下所示:

def Multiply[A](value: A, factor:Double)(implicit num: Numeric[A]) = num.toDouble(value)*factor
  def Poly[A](value:A, co:Array[Double])(implicit num: Numeric[A]) = { // do some poly math

解析字符串并不难,因为它非常简单。
如何动态地构建链?如果有用的话,在链的第一步,输入总是Long,结果可能是Long或者Double,如果我必须基于最终结果做两个版本,我可以接受,一个是Long到Long,另一个是Long到Double。
"我所尝试的"
如果我定义函数具有相同的签名,如下所示:

def Multiply(value: Double, factor:Double) = value*factor
  def Poly(value:Double, co:Array[Double]) = {

我可以将其作为Map操作的一部分来执行:

def ParseList(instruction:String) = {
    var instructions = instruction.split(';')

    instructions.map(inst => {
      val instParts = inst.split(Array(',','(',')'))
      val instruction = instParts(0).toUpperCase()
      val instArgs = instParts.drop(1).map(arg => arg.toDouble)
      instruction match {
        case "POLY" => (x: Double) => EUSteps.Poly(x,instArgs)
        case "MULTI" => (x: Double) => Multiply(x,instArgs(0))
      }
    }).reduceLeft((a,b) => a andThen b)

但是,只要我将其中一个参数或返回类型更改为Long,这种情况就会中断:

def Multiply(value: Long, factor:Double) = value*factor

改变我的案子

instruction match {
        case "POLY" => (x: Double) => EUSteps.Poly(x,instArgs)
        case "MULTI" => (x: Long) => Multiply(x,instArgs(0))
      }
    }).reduceLeft((a,b) => a andThen b)

现在Reduce正在抱怨,因为它想要Double =〉Double而不是Long =〉Double

stszievb

stszievb1#

一些想法:
1.预先分析字符串链,找出最终结果的类型,然后将其用于所有步骤,每种类型都需要一系列函数。
1.尝试在reduce部分使用Either[Long, Double]

相关问题