2013-10-16 12 views
18

In der funktionalen Programmierung mag Haskell, kann ich FunktionWie kann Go-lang Curry?

add a b = a+b 

Dann definieren add 3 eine Funktion zurück, die einen Parameter nehmen und kehrt 3 + something

Wie kann ich dies tun in GO?

Wenn ich eine Funktion definiere, die mehr als einen (zB n) Parameter benötigt, kann ich nur einen Parameter angeben und eine andere Funktion erhalten, die n-1 Parameter verwendet?

aktualisieren:

Sorry für die ungenauen Worte in meiner ursprünglichen Frage.

Ich denke, meine Frage als zwei qeustions gestellt werden soll:

  • Gibt es teilweise Anwendung in GO?
  • Wie GO funktioniert Curry?

Danke TheOnly92 und Alex für die Lösung meiner zweiten Frage. Ich bin aber auch neugierig auf die erste Frage.

+0

Haben Sie ein Beispiel aus der Praxis, wenn Sie das brauchen? –

Antwort

22

auf der vorherige Antwort zu erweitern, die Sie eine beliebige Anzahl von Argumenten nehmen kann:

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

Danke für Ihre Antwort. Es ist sehr hilfreich! Ich frage mich jedoch, ob es eine "teilweise Anwendung" in GO gibt? – lazywei

+0

Soweit mir bekannt ist, nein, aber Sie können eine "Fabrik" -Funktion machen, in der in diesem Fall eine Funktion, die eine andere Funktion auf eine bestimmte Weise erstellt. – TheOnly92

21

Vielleicht so etwas wie

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

Danke für diese Antwort! – lazywei

+0

Ich habe dies auf der mobilen Seite aufgewertet, aber ich muss den Downvote fett gefingert haben. Wenn Sie diese Antwort bearbeiten, kann ich den Fehler korrigieren. – weberc2

2

Sie können es noch einen Schritt weiter, indem Sie eine Funktion definieren, Geben Sie eine Methode ein und fügen Sie ihr eine Methode hinzu.

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

Sie können sogar mit variadische Funktionen versuchen:

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

hoffe, das hilft!