Dans cet article, je vais présenter la fonction d'ordre supérieur fournie par Nim et la comparer avec Python. Il comprend également des conseils sur la façon d'écrire Nim.
*** Efficace, expressif et élégant Nim est un langage de programmation système compilé de type statique. Il combine les concepts réussis de langages matures tels que Python, Ada et Modula. *** *** (Citation: https://nim-lang.org/ avec traduction Google) En bref, il a une syntaxe comme Python et est aussi rapide que le langage C. C'est un langage de rêve pour moi, qui écrit habituellement Python mais qui n'est pas satisfait de sa vitesse.
Une fonction d'ordre supérieur est une fonction *** qui prend une fonction *** comme argument. Il était utilisé dans les langages LISP et ML dans l'ancien temps, mais il a été implémenté dans de nombreux langages de programmation en raison de la récente montée en puissance des langages fonctionnels. Par exemple, il a été implémenté dans des langages de script tels que Python, et plus récemment en JavaScript (depuis ECMAScript 2015). Il semble qu'il puisse être écrit en Rust and Go, mais je ne le connais pas, je vais donc l'omettre.
Présentation des fonctions d'ordre supérieur implémentées dans le [module sequtil] de Nim (https://nim-lang.org/docs/sequtils.html) et leurs modèles.
map
map
proc map[T, S](s:openArray[T];op:proc(x:T):S{...}): seq[S] {...}
map
prend un tableau s
de type ʻopenArray et une procédure ʻop
comme arguments, et retourne seq
avec ʻop appliqué à chaque élément de
s. ʻOpenArray
est un type à usage général qui indique un tableau et inclut des séquences
, une chaîne
et une matrice
.
exemple de carte
import sequtils
let #Ceci est une déclaration de variable immuable
s = [1,2,3,4] #Ceci est un type de tableau
op = proc (x: int): int = x * x #Fonction anonyme, fonction qui retourne le carré de l'argument
echo s.map(op) # => @[1, 4, 9, 16] ##Chaque élément de s est au carré
echo s # => [1, 2, 3, 4] ##Le tableau d'origine ne change pas
echo s.map(op) == map(s, op) # => true
##Astuces Nim (Comment appeler une procédure)
## p(x)Et x.p()Est équivalent
apply
apply
proc apply[T](s:varopenArray[T];op:proc(x:T):T{...}) {...}
ʻApply a un tableau
s de type ʻopenArray
et une procédure ʻop comme arguments, et applique ʻop
à chaque élément de s
. Similaire à map
, mais ʻapply n'a pas de valeur de retour et modifie
s` directement. En fait, il existe une autre application, mais omise.
appliquer l'exemple
import sugar #Module expérimental
var #déclaration de variable mutable
x = [true, false, false, true, true]
echo x #=> [true, false, false, true, true]
apply(x, b => not b) #Ne prenez pas de chaque élément de x
echo x #=> [false, true, true, false, false]
##Astuces Nim (Comment écrire des fonctions anonymes)
## b =>not b est une abréviation de fonction anonyme. Le côté gauche est l'argument et le côté droit est la valeur de retour
##Cependant, l'importation de sucre est requise
filter
filter
proc filter[T](s:openArray[T];pred:proc(x:T):bool{...}): seq[T] {...}
filter
prend un tableau s
de type ʻopenArray et une procédure
pred comme arguments, et renvoie
seq constitué d'éléments de
spour lesquels
pred renvoie
true`.
exemple de filtre
import strutils
let
str = "happY holidAYs"
upperStr = str.filter(s => s.isUpperAscii()) #Filtre en majuscules
echo str #=> "happY holidAYs"
echo upperStr #=> @['Y', 'A', 'Y']
echo upperStr.join("") #=> "YAY" ##Combiner des éléments d'un tableau de type chaîne(Identique à Python)
##Astuces Nim (dénomination)
##Il est recommandé de déclarer les variables et les procédures Nim dans camelCase.
keepIf
keepIf
proc keepIf[T](s:varseq[T];pred:proc(x:T):bool{...}) {...}
keepIf
prend s
de type seq
et procedure pred
comme arguments, et ne laisse que les éléments pour lesquels pred
renvoie true
dans s
. Cependant, notez que l'argument est seq
au lieu de ʻopenArray`.
Ce sont respectivement les modèles map, apply, filter et keepIf
. Avec ceux-ci, vous pouvez facilement (juste un peu) appeler des fonctions d'ordre supérieur. Puisque l'utilisation est presque la même, je vais vous présenter un exemple de mapIt
.
exemple mapIt
let
v = [1,2,3,4,5]
w = v.mapIt(it*2) #cela signifie chaque élément de v, ce qui signifie doubler chaque élément
echo w # => @[2, 4, 6, 8, 10]
point
--Les arguments de mapIt
(et ainsi de suite) sont des tableaux et des ** expressions **
--ʻIt` dans le modèle est chaque élément du tableau d'arguments
seq
comme la fonction d'originePython implémente également map, filter, reduction (correspondant à foldl, foldr), mais il n'y a pas d'équivalent à apply ou keepIf (en pandas). Par conséquent, si vous souhaitez utiliser la liste après avoir multiplié la liste l
par map
,
l = [1, 2, 3, 4] #Je veux doubler chaque valeur
mapped_l = map(lambda x: x*2, l) # mapped_ce n'est pas une liste
assert type(mapped_l) is map # => true
mapped_l = list(mapped_l) #Revenir à la liste
Doit être. Le type de retour de «map» est «map object», qui est différent de l'argument. Il s'agit d'un générateur, donc si vous souhaitez l'utiliser comme type d'origine, vous devez le renvoyer explicitement. Il en va de même pour «filter», et la valeur de retour de «filter» est «filter object». Par exemple
l = [-3, -2, -1, 0, 1, 2, 3]
p = filter(lambda x: x>0, l) #Ne laissez que des éléments positifs
len(p) #Erreur car p est un objet filtre
len(list(p)) #C'est d'accord. La réponse est 3
len([li for li in l if li > 0]) #Ceci est également correct. Est-ce une manière d'écrire plus Python? ?? ??
Personnellement, je n'aime pas beaucoup ça. Dans le cas de Nim, le type de retour de l.map (proc ...)
est seq
, il est donc facile à utiliser car il n'y a pas besoin d'un tel traitement (impression personnelle).
J'ai résumé les fonctions d'ordre supérieur de Nim. Nim est encore une langue en développement, mais j'espère qu'elle se développera davantage à l'avenir. J'espère que cela aide un peu tout le monde: upside_down: