Question

Pouvez-vous passer à une opération comme " diviser par 2 " ou " soustrayez 1 " en utilisant seulement un opérateur partiellement appliqué, où " add 1 " ressemble à ceci:

List.map ((+) 1) [1..5];;  //equals [2..6]
// instead of having to write: List.map (fun x-> x+1) [1..5]

Ce qui se passe est que 1 est appliqué à (+) en tant que premier argument et que l'élément de liste est appliqué en tant que second argument. Pour l'addition et la multiplication, l'ordre des arguments n'a pas d'importance.

Supposons que je veuille soustraire 1 à chaque élément (ce sera probablement une erreur courante des débutants):

List.map ((-) 1) [1..5];;  //equals [0 .. -4], the opposite of what we wanted

1 est appliqué au (-) comme premier argument, donc au lieu de (list_item - 1), j'obtiens (1 - list_item). Je peux le réécrire en ajoutant un négatif au lieu de soustraire un positif:

List.map ((+) -1) [1..5];;
List.map (fun x -> x-1) [1..5];; // this works too

Je cherche un moyen plus expressif de l'écrire, comme ((-) _ 1), où _ désigne un espace réservé, comme dans le langage Arc. Cela ferait de 1 le deuxième argument de -. Dans List.map, la valeur serait donc list_item - 1. Donc, si vous voulez mapper divide by 2 à la liste, vous pouvez écrire:

List.map ((/) _ 2) [2;4;6] //not real syntax, but would equal [1;2;3] 
List.map (fun x -> x/2) [2;4;6] //real syntax equivalent of the above

Est-ce possible ou dois-je utiliser (fun x -> x/2)? Il semble que le plus proche de la syntaxe des espaces réservés consiste à utiliser un lambda avec un argument nommé.

Était-ce utile?

La solution

Vous pouvez écrire une fonction d'inversion, par exemple:

let flip f x y = f y x

List.map (flip (-) 1) [2;4;6]

La syntaxe est peut-être incorrecte, je ne parle pas couramment le fa #.

Autres conseils

Il n'y a pas de 'sections d'opération' dans F #, à la Haskell, ni d'argument d'espace réservé (apparemment à la Arc). Vous pouvez utiliser un combinateur "inversé" comme suggéré dans une autre réponse pour inverser l'ordre des arguments, puis appliquer partiellement le premier argument (maintenant le second).

Mais je voudrais simplement utiliser

fun x -> x / 2

À moins que vous ne jouiez au code-golf, je ne pense pas que tenter de réduire de nouveau quelques personnages vous rapporte quelque chose.

La solution flip suggérée par Logan Capaldo peut également être écrite à l'aide d'un opérateur (ici >. ):

let (>.) x f = (fun y -> f y x)
List.map (1 >. (-)) [2;4;6]

Ou si vous préférez les opérandes dans le sens inverse:

let (>.) f x = (fun y -> f y x)
List.map ((-) >. 1) [2;4;6]

Modifier: l'utilisation d'un opérateur qui "ressemble davantage à un espace réservé". (ici > - < ) vous rapproche beaucoup de la syntaxe proposée:

List.map ((-) >-< 1) [2;4;6]

'_' n'est malheureusement pas (?) pas a symbole d'opérateur valide en F # .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top