texto - ¿Cuál es el equivalente de foldr, foldl en Emacs Lisp?
emacs source code (3)
Si tu
(require ''cl)
entonces puedes usar la función Common Lisp reduce
. Pase el argumento de la palabra clave :from-end t
para foldr
.
ELISP> (reduce #''list ''(1 2 3 4))
(((1 2) 3) 4)
ELISP> (reduce #''list ''(1 2 3 4) :from-end t)
(1 (2 (3 4)))
¿Cuál es el equivalente de foldr, foldl en Emacs Lisp?
La biblioteca Common Lisp proporciona muchas funciones de secuencia como mapeo, filtrado, plegado, búsqueda e incluso clasificación. La biblioteca CL se envía con Emacs de forma predeterminada, por lo que debe atenerse a ella. Sin embargo, me gusta dash.el
biblioteca dash.el
, ya que proporciona enormes cantidades de funciones para manipulación de listas y árboles. También admite macros anafóricas y fomenta la programación funcional, lo que hace que el código sea conciso y elegante.
Los pliegues de Haskell se corresponden con los pliegues de dash.el
:
-
foldl
con-reduce-from
-
foldr
con-reduce-r-from
-
foldl1
con-reduce
-
foldr1
con-reduce-r
La suma de un rango de 1 a 10 usando pliegues puede ser similar a esto en Haskell y dash.el
:
foldl (+) 0 [1..10] -- Haskell
(-reduce-from ''+ 0 (number-sequence 1 10)) ; Elisp
Es probable que sepa que los pliegues son muy generales y que es posible implementar mapas y filtros a través de pliegues. Por ejemplo, para incrementar cada elemento por 2, el currying y las secciones de Haskell permitirían el código de latencia, pero en Elisp normalmente escribirías lambdas desechables como las siguientes:
foldr ((:) . (+2)) [] [1..10] -- Haskell
(-reduce-r-from (lambda (x acc) (cons (+ x 2) acc)) ''() (number-sequence 1 10)) ; Elisp
Adivina qué, no es necesario en dash.el
con macros anafóricas, que permiten una sintaxis especial al exponer variables de un lambda como accesos directos, como it
y acc
en pliegues. Las funciones anafóricas comienzan con 2 guiones en lugar de 1:
(--reduce-r-from (cons (+ it 2) acc) ''() (number-sequence 1 10))
Hay muchas funciones tipo dash.el
en dash.el
:
;; Count elements matching a predicate
(-count ''evenp ''(1 2 3 4 5)) ; 2
;; Add/multiply elements of a list together
(-sum ''(1 2 3 4 5)) ; 15
(-product ''(1 2 3 4 5)) ; 120
;; Find the smallest and largest element
(-min ''(3 1 -1 2 4)) ; -1
(-max ''(-10 0 10 5)) ; 10
;; Find smallest/largest with a custom rule (anaphoric versions)
(--min-by (> (length it) (length other)) ''((1 2 3) (4 5) (6))) ; (6)
(--max-by (> (length it) (length other)) ''((1 2 3) (4 5) (6))) ; (1 2 3)
Desde Emacs-24.3 recomendamos el uso de cl-lib
sobre cl
(que se planea eliminar en un futuro lejano), por lo que sería:
(require ''cl-lib)
(cl-reduce #''list ''(1 2 3 4))
y desde Emacs-25, también puedes usar el paquete seq
para eso:
(require ''seq)
(seq-reduce #''list ''(1 2 3 4))