2013-10-16 102 views
18

在函数式编程Haskell的喜欢,我可以定义功能怎么去朗朗咖喱?

add a b = a+b 

然后add 3将返回取一个参数,并返回3 + something

我怎样才能做到这一点GO功能?

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

更新

对不起,在我原来的问题不精确的话。

我觉得我的问题应该问两个qeustions:

  • 是否有GO部分应用程序?
  • 如何去做功能咖喱?

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

+0

你有什么时候需要这个的真实世界的例子吗? –

回答

22

为了扩展在以前的答案,它允许你利用参数任意数量的:通过定义一个函数

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

感谢您的回答。这非常有帮助!但是,我想知道GO中是否存在“部分应用”? – lazywei

+0

据我所知,不,但你可以做一个“工厂”功能,在这种情况下,像这种情况下,一个功能,以特定的方式创建另一个功能。 – TheOnly92

21

也许类似

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

感谢您的回答! – lazywei

+0

我在移动网站上投了这个赞,但我必须发短信给胖子。如果你编辑这个答案,我可以纠正这个错误。 – weberc2

2

你可以把它一步键入并添加一个方法。

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

希望这有助于!