Как можно пойти карри?
В функциональном программировании любит Haskell, я могу определить функцию
add a b = a+b
затем add 3
вернет функцию, которая принимает один параметр и вернет 3 + something
Как я могу сделать это в GO?
Когда я определяю функцию, которая принимает более одного (скажем, n) параметра, могу ли я дать ей только один параметр и получить другую функцию, которая принимает n-1 параметров?
Обновление:
Извините за неточные слова в моем оригинальном вопросе.
Я думаю, что мой вопрос должен быть задан в виде двух вопросов:
- Есть ли частичное применение в GO?
- Как GO сделать функцию карри?
Спасибо TheOnly92 и Алексу за решение моего второго вопроса. Однако мне также любопытен первый вопрос.
3 ответа
Для продолжения предыдущего ответа, который позволяет принять произвольное количество аргументов:
package main
import (
"fmt"
)
func mkAdd(a int) func(...int) int {
return func(b... int) int {
for _, i := range b {
a += i
}
return a
}
}
func main() {
add2 := mkAdd(2)
add3 := mkAdd(3)
fmt.Println(add2(5,3), add3(6))
}
Возможно что-то вроде
package main
import (
"fmt"
)
func mkAdd(a int) func(int) int {
return func(b int) int {
return a + b
}
}
func main() {
add2 := mkAdd(2)
add3 := mkAdd(3)
fmt.Println(add2(5), add3(6))
}
Вы можете сделать шаг вперед, определив тип функции, а затем добавив к ней метод.
package main
import "fmt"
type Add func(int, int) int
func (f Add) Apply(i int) func(int) int {
return func(j int) int {
return f(i, j)
}
}
func main() {
var add Add = func(i, j int) int { return i + j }
add3 := add.Apply(3)
fmt.Println("add 3 to 2:", add3(2))
}
Вы даже можете попробовать с переменными функциями:
package main
import "fmt"
type Multiply func(...int) int
func (f Multiply) Apply(i int) func(...int) int {
return func(values ...int) int {
values = append([]int{i}, values...)
return f(values...)
}
}
func main() {
var multiply Multiply = func(values ...int) int {
var total int = 1
for _, value := range values {
total *= value
}
return total
}
var times2 Multiply = multiply.Apply(2)
fmt.Println("times 2:", times2(3, 4), "(expect 24)")
// ... and you can even cascade (if assigned the Multiply type)
times6 := times2.Apply(3)
fmt.Println("times 6:", times6(2, 3, 5, 10), "(expect 1800)")
}
Надеюсь это поможет!