В Scala оператор for ... yield отлично подходит для объединения последовательности вызовов функций для определения графа преобразований с использованием методов монад. Однако я хотел бы определить вызовы функций вне области действия функции и передать их динамически, чтобы вызовы связанных функций могли быть определены другим приложением и переданы в качестве аргумента с использованием строки.
Согласно для scala языка spe c тип данных, используемый for ... yield, является перечислением, но я могу найти только жестко закодированные примеры перечислений.
Is есть способ динамически сгенерировать перечисление и передать его в оператор 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, Int] = Map("val1"->1,"val2"->2,"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
Редактирование: похоже, что единственный способ передать функции в виде строки - использовать компиляцию во время выполнения, как в следующем примере: Как преобразовать строку из текстового ввода в функцию в 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