2013-10-16 5 views
18

Dans la programmation fonctionnelle Haskell aime, je peux définir la fonctionComment go-lang curry?

add a b = a+b 

Puis add 3 retourne une fonction qui prend un paramètre et retournera 3 + something

Comment puis-je faire dans GO?

Lorsque je définis une fonction qui prend plus d'un (disons n) paramètres, puis-je lui donner seulement un paramètre et obtenir une autre fonction qui prend n-1 paramètres?

Mise à jour:

Désolé pour les mots imprécis dans ma question initiale.

Je pense que ma question devrait être posée deux qeustions:

  • Y at-il une application partielle dans GO?
  • Comment GO fonctionne-t-il?

Merci TheOnly92 et Alex pour avoir résolu ma deuxième question. Cependant, je suis également curieux de la première question.

+0

Avez-vous un exemple concret de quand vous en avez besoin? –

Répondre

22

Pour étendre la réponse précédente, ce qui vous permet de prendre un nombre arbitraire d'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)) 
} 
+0

Merci pour votre réponse. C'est très utile! Cependant, je me demande s'il y a une «application partielle» dans GO? – lazywei

+0

Pour autant que je sache, non, mais vous pouvez faire une fonction "usine" dans laquelle, comme ce cas, une fonction qui crée une autre fonction d'une manière spécifique. – TheOnly92

21

Peut-être quelque chose comme

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

Merci pour cette réponse! – lazywei

+0

J'ai mis en ligne ceci sur le site mobile, mais je dois avoir gros-doigts la downvote. Si vous modifiez cette réponse, je peux corriger l'erreur. – weberc2

2

Vous pouvez prendre un peu plus loin en définissant une fonction tapez puis ajoutez-y une méthode.

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

Vous pouvez même essayer avec des fonctions variadique:

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!