如何在Go语言中进行柯里化?

28

在类似 Haskell 的函数式编程语言中,我可以定义函数。

add a b = a+b

那么add 3将返回一个函数,该函数需要一个参数,并返回3 + something

我如何在GO中实现这个功能?

当我定义一个函数需要多于一个(比如n个)参数时,我只能给它一个参数并获取另一个只需n-1个参数的函数吗?

更新:

抱歉我的原始问题措辞不够准确。

我认为我的问题应该分为两个:

  • GO中是否支持部分应用程序?
  • GO如何进行函数柯里化?

感谢TheOnly92和Alex解决了我的第二个问题。但是,我也对第一个问题很感兴趣。

3个回答

32
也许类似于:
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))
}

32
为了进一步说明之前的答案,它允许您使用任意数量的参数:
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))
}

1
谢谢你的回答。非常有帮助!不过,我想知道GO语言中是否有“部分应用”? - lazywei
据我所知,不行,但是你可以创建一个“工厂”函数,就像这种情况下创建另一个特定方式的函数。 - TheOnly92

7
你可以进一步定义一个函数类型,然后添加一个方法。
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)")
}

希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接