Как создать функциональные каналы для функций / методов в Groovy? - PullRequest
0 голосов
/ 27 сентября 2019

Я хочу создать каналы для соединения вызовов функций (методов) Groovy, как это делается в других функциональных языках, таких как F #:

 let print message =
     printf "%s" message

 // "Hello World" will be passed as a parameter to the print function
 "Hello World" |> print

Существует наивная реализация, использующая оператор or:

Object.metaClass.or { it -> it(delegate)}

def print = { msg ->
    println msg
}

"Hello World" | print      //Hello World

Но это работает только для функций с 1 параметром.Для дополнительных параметров необходимо использовать rcurry:

Object.metaClass.or { it -> it(delegate)}

def print = { msg1, msg2 ->
    println msg1 + msg2
}

"Hello World" | print.rcurry('!!!')   //Hello World!!!

Есть ли способ избавиться от метода rcurry и сделать код Groovy более похожим на F #?Кстати, эта наивная реализация работает только для файлов скриптов Groovy.Как мне заставить его работать и для файлов классов?

Примечание: в Groovy есть и другие вопросы о каналах, но они касаются каналов для команд оболочки, а не функций.

Ответы [ 3 ]

0 голосов
/ 28 сентября 2019

Похоже, вы просто хотите with и использовать .& для преобразования методов в Closures и >> для композиции функций.

public static String addExclamations(String s) { 
    return s + "!!!"
} 

Closure printUppercase = { String s -> println s.toUpperCase() }

"Hello World".with (this.&addExclamations >> printUppercase)

Пример из реального мира, в котором я использую всевремя:

import groovy.json.JsonOutput

[a:[b:'c', d:'e']].with (JsonOutput.&toJson >> JsonOutput.&prettyPrint)        

Я не уверен, что вы делаете с многопараметрическим материалом, потому что различные решения curry кажутся мне разумными, но вы это отклонили ... возможно, яможете отредактировать этот ответ, если вы можете привести пример того, как бы вы хотели, чтобы он выглядел?

0 голосов
/ 28 сентября 2019

ближайший по умолчанию синтаксис groovy

def c = {'hello'}>>{"$it !!!"}>>{println it}
c()

используйте столько параметров, сколько хотите

0 голосов
/ 27 сентября 2019

не может понять причину этого синтаксиса, однако работает следующий пример:

Object.metaClass.or = { it -> 
    def r=it.call(delegate)
}

//this will be called for case without parameters
def getGreet(){
    return {greet-> println "$greet world"}
}

//this will be called for case with one parameter
def greet(name){
    return {greet-> println "$greet $name" }
}

'hi'|greet('jack')
'hello'|greet

print

hi jack
hello world
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...