Подтвердить что ты не робот

Как можно пойти карри?

В функциональном программировании нравится Haskell, я могу определить функцию

add a b = a+b

Затем add 3 вернет функцию, которая принимает один параметр и вернет 3 + something

Как я могу сделать это в GO?

Когда я определяю функцию, которая принимает более одного (скажем n) параметров, могу ли я дать только один параметр и получить другую функцию, которая принимает n-1 параметров?

Обновление

Извините за неточные слова в моем исходном вопросе.

Я думаю, что мой вопрос должен задаваться как два вопроса:

  • Есть ли частичное приложение в GO?
  • Как GO выполняет функцию карри?

Спасибо TheOnly92 и Alex за решение моего второго вопроса. Однако мне также интересен первый вопрос.

4b9b3361

Ответ 1

Чтобы расширить предыдущий ответ, который позволяет принимать произвольное количество аргументов:

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))
}

Ответ 2

Возможно, что-то вроде

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))
}

Ответ 3

Вы можете сделать еще один шаг, указав тип функции, а затем добавив к ней метод.

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)")
}

Надеюсь, это поможет!