Подтвердить что ты не робот

Что эквивалентно foldr, foldl в Emacs Lisp?

Что эквивалентно foldr, foldl в Emacs Lisp?

4b9b3361

Ответ 1

Если вы

(require 'cl)

то вы можете использовать функцию Common Lisp reduce. Передайте аргумент ключевого слова :from-end t для 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)))

Ответ 2

Начиная с Emacs-24.3 мы рекомендуем использовать cl-lib над cl (который планируется удалить в каком-то отдаленном будущем), поэтому это будет:

(require 'cl-lib)
(cl-reduce #'list '(1 2 3 4))

а с Emacs-25 вы также можете использовать пакет seq для этого:

(require 'seq)
(seq-reduce #'list '(1 2 3 4))

Ответ 3

Общая библиотека Lisp предоставляет множество функций последовательности как отображение, фильтрация, свертывание, поиск и даже сортировка. Библиотека CL поставляется с Emacs по умолчанию, поэтому вы должны придерживаться ее. Мне действительно нравится библиотека dash.el, поскольку она предоставляет огромное количество функций для манипуляций списком и деревом. Он также поддерживает анафорические макросы и поощряет функциональное программирование, что делает код кратким и элегантным.

Складки Haskell соответствуют складкам dash.el:

Сумма диапазона от 1 до 10 с использованием складок может выглядеть в этом в Haskell и dash.el:

foldl (+) 0 [1..10] -- Haskell
(-reduce-from '+ 0 (number-sequence 1 10)) ; Elisp

Вы, наверное, знаете, что складки очень общие, и можно реализовать карты и фильтры с помощью сгибов. Например, чтобы увеличить каждый элемент на 2, каркасы и секции Haskell позволят использовать краткий код, но в Elisp вы обычно пишете многословные выбросы лямбда:

foldr ((:) . (+2)) [] [1..10] -- Haskell
(-reduce-r-from (lambda (x acc) (cons (+ x 2) acc)) '() (number-sequence 1 10)) ; Elisp

Угадайте, что нет необходимости в dash.el с анафорическими макросами, которые допускают специальный синтаксис, выставляя переменные лямбды как ярлыки, например it и acc в складках. Анафорические функции начинаются с 2 тире вместо 1:

(--reduce-r-from (cons (+ it 2) acc) '() (number-sequence 1 10))

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