Вот упрощенная версия проекта, который пытается создать функцию во время выполнения. Таким образом, pipelineS
приходит во время выполнения (в форме json или чего-то еще), и траверс выполняет его. Кроме того, мы знаем, что входные данные во время выполнения будут корректной композицией (совпадение типов входных / выходных функций). Я хочу определить функции, которые имеют информацию о типе и избегают asInstanceOF
. Вот частичное решение, которое я вижу: Здесь , но оно очень сложное и его сложно расширить до входных аргументов другого размера.
abstract class Func extends Product {
val meta:FuncMeta
}
case class FuncMeta(name:String, outType:String, inTypes:List[String])
case class Fun0(meta:FuncMeta, run:() => Any) extends Func
case class Fun1(meta:FuncMeta, run:Any => Any) extends Func
case class Fun2(meta:FuncMeta, run:(Any, Any) => Any) extends Func
val literal2 = Fun0(FuncMeta("literal2", "int", List.empty), () => 2)
val literal10 = Fun0(FuncMeta("literal10", "int", List.empty), () => 10)
val twice = Fun1(FuncMeta("twice", "int", "int" :: Nil) ,(a:Any) => a.asInstanceOf[Int] * 2)
val larger = Fun2(FuncMeta("larger", "bool", "int" :: "int" :: Nil) ,(a:Any, b:Any) => a.asInstanceOf[Int] > b.asInstanceOf[Int])
val add = Fun2(FuncMeta("add", "int", "int" :: Nil), (a:Any, b:Any) => a.asInstanceOf[Int] + b.asInstanceOf[Int])
//a Map[String, Func] for runtime access and retreave of functions
//Basically this is the way the Functions are stored
val funcs = List(literal2, literal10, twice, larger, add).map(x => x.meta.name -> x).toMap
def traverse(tree: Treee[Func]):Any = {
val t = tree.t
val kids = tree.kids
val rs = kids.map(k => traverse(k))
t match {
case Fun0(meta, run) => run()
case Fun1(meta, run) => run(rs.head)
case Fun2(meta, run) => run(rs(0), rs(1))
}
}
//RUNTIME information
//can be a userinput Json that get's converted to the following by accessing the funcs Map
val pipelineS = Treee[Func](
funcs("larger"),
List(
Treee(funcs("literal10")),
Treee(funcs("literal2"))
)
)
println(traverse(pipelineS))