2013-10-16 16 views
18

In programmazione funzionale Haskell piace, posso definire funzioneCome può andare-lang curry?

add a b = a+b 

Poi add 3 restituirà una funzione che prende un parametro e tornerà 3 + something

Come posso fare questo in GO?

Quando definisco una funzione che richiede più di un parametro (say n), posso dargli solo un parametro e ottenere un'altra funzione che prenda i parametri n-1?

Aggiornamento:

Scusate le parole imprecise nella mia domanda iniziale.

Penso che la mia domanda si dovrebbe chiedere come due qeustions:

  • C'è parziale applicazione in GO?
  • Come funziona GO curry?

Grazie TheOnly92 e Alex per aver risolto la mia seconda domanda. Tuttavia, sono anche curioso della prima domanda.

+0

Hai un esempio reale di quando hai bisogno di questo? –

risposta

22

Per estendere sulla risposta precedente, che permette di prendere un numero arbitrario di argomenti:

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

Grazie per la risposta. È molto utile! Tuttavia, mi chiedo se ci sia "applicazione parziale" in GO? – lazywei

+0

Per quanto ne so, no, ma è possibile creare una funzione "fabbrica" ​​in cui, in questo caso, una funzione crea un'altra funzione in un modo specifico. – TheOnly92

21

Forse qualcosa di simile

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

Grazie per questa risposta! – lazywei

+0

Ho svalutato questo sul sito per dispositivi mobili, ma devo avere le dita grasse del downvote. Se modifichi questa risposta, posso correggere l'errore. – weberc2

2

si può prendere un ulteriore passo avanti definendo una funzione digitare e quindi aggiungere un metodo ad esso.

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

Si può anche provare con funzioni variadic:

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

Spero che questo aiuti!

Problemi correlati