在Scala中,for ... yield语句非常适合将一系列函数调用链接在一起,以使用monad实践定义转换图。但是,我想在函数范围之外定义函数调用,并动态传递它们,以便链接的函数调用可以由另一个应用程序定义,并使用字符串作为参数传递。
根据scala language spec,for ... yield使用的数据类型是枚举,但是我只能找到枚举的硬编码示例。
是否可以动态生成枚举并将其传递给for ... yield语句?
例如,给出以下工作代码:
import scala.util.Try
val map1: Map[String,Int] = Map("val1"->1,"val2"->2,"val3"->3)
def mapTest(inputMap: Map[String,Int]) = {
for {
x <- Try(inputMap.mapValues(_ * 2))
y <- Try(x.mapValues(_ * 2))
z <- Try(y.mapValues(_ *2))
} yield z
}
mapTest(map1).get
以如下方式运行它,其中功能列表作为functionList(伪代码)传递进来:
import scala.util.Try
val map1: Map[String,"val3"->3)
val functionList: String = "(x <- Try(inputMap.mapValues(_ * 2))),(y <- Try(x.mapValues(_ * 2))),(z <- Try(y.mapValues(_ *2)))"
def mapTest(inputMap: Map[String,Int],functionList: String) = {
for {functionList.toEnum} yield z
}
mapTest(map1).get
编辑:像字符串一样,传递函数的唯一方法似乎是使用运行时编译,例如以下示例:How to convert a string from a text input into a function in a Scala
这里还有更多示例:https://docs.scala-lang.org/overviews/repl/embedding.html
与运行功能列表不同,这是一个不同的问题。我需要一种将包含函数列表的字符串转换为实际函数的方法。
基本上,需要将类似此字符串的内容传递到运行时编译器代码中,然后运行mapTest(inputMap)来返回新的映射z。
val functionString = s"""
def mapTest(inputMap: Map[String,Int]) = {
| for {
| x <- Try(inputMap.mapValues(_ * 2))
| y <- Try(x.mapValues(_ * 2))
| z <- Try(y.mapValues(_ *2))
| } yield z
|}""".stripMargin