什么相当于Emacs Lisp中的foldr,foldl?

Tho*_*mas 23 lisp emacs elisp

什么相当于Emacs Lisp中的foldr,foldl?

Gar*_*ees 27

If you

(require 'cl)
Run Code Online (Sandbox Code Playgroud)

then you can use the Common Lisp function reduce. Pass the keyword argument :from-end t for 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)))
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 18

从Emacs-24.3开始,我们建议使用cl-libover cl(计划在不久的将来删除),因此它将是:

(require 'cl-lib)
(cl-reduce #'+ '(1 2 3 4))
Run Code Online (Sandbox Code Playgroud)

从Emacs-25开始,您也可以使用该seq软件包:

(require 'seq)
(seq-reduce #'+ '(1 2 3 4) 0)
Run Code Online (Sandbox Code Playgroud)

  • 这最好是对Gareth Rees答案的评论,而不是对其本身的单独答案的评论. (3认同)

Mir*_*lov 6

Common 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
Run Code Online (Sandbox Code Playgroud)

您可能知道,折叠是非常通用的,并且可以通过折叠实现贴图和过滤器.例如,要将每个元素递增2,Haskell的currying和section将允许简洁的代码,但在Elisp中,您通常会编写详细的一次性lambdas:

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

猜猜是什么,没有必要dash.el使用回指宏,它允许通过将lambda的变量暴露为快捷方式(如itacc在折叠中)来实现特殊语法.回指函数以2个破折号而不是1个开头:

(--reduce-r-from (cons (+ it 2) acc) '() (number-sequence 1 10))
Run Code Online (Sandbox Code Playgroud)

有很多类似折叠的功能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)
Run Code Online (Sandbox Code Playgroud)