How can go-lang curry?

15,266

Solution 1

To extend on the previous answer, which allows you to take an arbitrary number of arguments:

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

Solution 2

Perhaps something like

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

Solution 3

You can take it a step further by defining a function type and then adding a method to it.

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

You can even try with variadic functions:

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

Hope this helps!

Share:
15,266

Related videos on Youtube

lazywei
Author by

lazywei

Updated on July 27, 2022

Comments

  • lazywei
    lazywei almost 2 years

    In functional programming likes Haskell, I can define function

    add a b = a+b
    

    Then add 3 will return a function that take one parameter and will return 3 + something

    How can I do this in GO?

    When I define a function that take more than one (say n) parameters, can I only give it one parameter and get another function that take n-1 parameters?

    Update:

    Sorry for the imprecise words in my original question.

    I think my question should be asked as two qeustions:

    • Is there partial application in GO?
    • How GO do function curry?

    Thanks TheOnly92 and Alex for solving my second question. However, I am also curious about the first question.

  • lazywei
    lazywei over 10 years
    Thanks for your answer. It's very helpful! However, I wonder whether there is 'partial application' in GO?
  • TheOnly92
    TheOnly92 over 10 years
    As far as I'm aware, no, but you can make a "factory" function in which like this case a function that creates another function in a specific way.