2013-05-14 1 views
10

Existe-t-il un moyen d'écrire une fonction infixe sans utiliser de symboles? Quelque chose comme ceci:Comment écrire une fonction infixe

let mod x y = x % y 
x mod y 

Peut-être un mot-clé avant "mod" ou quelque chose.

+0

Vous pourriez être intéressé par [ce problème UserVoice] (http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2313479-provide-the-option-of-having-infix-notation- amusant). – Daniel

+0

http://stackoverflow.com/questions/2210854/can-you-define-your-own-operators-in-f – ony

Répondre

16

La réponse actuelle est correcte - vous ne pouvez pas définir une fonction infixe en F # (juste un opérateur infixe personnalisé). Mis à part le tour avec les opérateurs de tuyaux, vous pouvez également utiliser des éléments d'extension:

// Define an extension member 'modulo' that 
// can be called on any Int32 value 
type System.Int32 with 
    member x.modulo n = x % n 

// To use it, you can write something like this: 
10 .modulo 3 

Notez que l'espace avant . est nécessaire, car sinon le compilateur essaie d'interpréter 10.m comme un littéral numérique (comme 10.0f). Je trouve cela un peu plus élégant que l'utilisation de pipeline, car F # supporte à la fois le style fonctionnel et le style orienté objet et les méthodes d'extension sont en quelque sorte proches des opérateurs implicites du style fonctionnel. L'astuce du pipeline ressemble à une légère utilisation abusive des opérateurs (et cela peut paraître confus au début - peut-être plus déroutant qu'une invocation de méthode).

Cela dit, je l'ai vu des gens qui utilisent d'autres opérateurs au lieu de pipeline - peut-être la version la plus intéressante est celle-ci (qui utilise également le fait que vous pouvez omettre les espaces autour des opérateurs):

// Define custom operators to make the syntax prettier 
let (</) a b = a |> b 
let (/>) a b = a <| b  
let modulo a b = a % b 

// Then you can turn any function into infix using: 
10 </modulo/> 3 

Mais même Ce n'est pas vraiment un idiome établi dans le monde F #, donc je préférerais probablement encore les membres de l'extension.

+1

Cela fait longtemps que je n'ai rien écrit/codé, mais cela ressemble à la même chose que les méthodes d'extension en C#. Doux! – Iter

+2

@Iter Ceci est ** une ** méthode d'extension :) –

+2

Désolé pour commenter cet ancien post, mais votre paire d'opérateurs est fausse: en raison de la précédence de l'opérateur, '10 3' est équivalent à' modulo 3 10', pas 'modulo 10 3'. Une solution consiste à définir 'let (/>) f x y = f y x' à la place. Ou vous pouvez utiliser une autre paire d'opérateurs avec la bonne précédence, comme '<.' and '.>'. – Tarmil

6

Pas que je sache, mais vous pouvez utiliser les opérateurs de tuyau gauche et droite. Par exemple

let modulo x y = x % y 

let FourMod3 = 4 |> modulo <| 3 
+0

Ci-dessus est considéré comme 'pseudo infixe' rien à redire, il suffit de pointer En fait, j'aime bien cette notation parfois – BoomTownTech