Tương đương với foldr, foldl trong Emacs Lisp là gì?Tương đương với foldr, foldl trong Emacs Lisp là gì?
Trả lời
Nếu bạn
(require 'cl)
sau đó bạn có thể sử dụng chức năng Common Lisp reduce
. Vượt qua đối số từ khóa :from-end t
cho 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)))
Kể từ Emacs-24,3, chúng tôi khuyến cáo sử dụng cl-lib
qua cl
(được lên kế hoạch để loại bỏ trong một số tương lai xa), vì vậy nó sẽ là:
(require 'cl-lib)
(cl-reduce #'list '(1 2 3 4))
và kể từ Emacs-25, bạn cũng có thể sử dụng gói seq
cho rằng:
(require 'seq)
(seq-reduce #'list '(1 2 3 4))
Common Lisp library cung cấp nhiều sequence functions như lập bản đồ, fil tering, gấp, tìm kiếm và thậm chí phân loại. Thư viện CL được vận chuyển với Emacs theo mặc định, vì vậy bạn nên dính vào nó. Tuy nhiên tôi thực sự thích thư viện dash.el
, bởi vì nó cung cấp một lượng lớn các hàm cho các thao tác danh sách và cây. Nó cũng hỗ trợ anaphoric macros và khuyến khích lập trình hàm, làm cho mã ngắn gọn và thanh lịch.
nếp gấp của Haskell tương ứng với dash.el
nếp gấp:
foldl
với-reduce-from
foldr
với-reduce-r-from
foldl1
với-reduce
foldr1
với-reduce-r
Sum của một loạt 1-10 sử dụng nếp gấp có thể trông giống như trong này trong Haskell và dash.el
:
foldl (+) 0 [1..10] -- Haskell
(-reduce-from '+ 0 (number-sequence 1 10)) ; Elisp
Bạn có thể biết, rằng nếp gấp là rất chung chung, và nó có thể thực hiện bản đồ và các bộ lọc thông qua nếp gấp . Ví dụ, để tăng mọi phần tử của 2, currying và phần Haskell sẽ cho phép cho mã ngắn gọn, nhưng trong elisp bạn thường sẽ viết lambdas verbose throwaway như thế:
foldr ((:) . (+2)) [] [1..10] -- Haskell
(-reduce-r-from (lambda (x acc) (cons (+ x 2) acc)) '() (number-sequence 1 10)) ; Elisp
Đoán những gì, nó không phải là cần thiết trong dash.el
với các macro ẩn danh, cho phép cú pháp đặc biệt bằng cách hiển thị các biến của lambda dưới dạng các phím tắt, như it
và acc
trong các nếp gấp. chức năng Anaphoric bắt đầu với 2 dấu gạch ngang thay vì 1:
(--reduce-r-from (cons (+ it 2) acc) '() (number-sequence 1 10))
Có rất nhiều lần giống như chức năng trong 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)
này tốt hơn nên có một bình luận cho Gareth Rees' câu trả lời hơn là một câu trả lời riêng biệt trong nó quyền sở hữu. – Thomas
@Thomas Không thể viết nhận xét nhiều dòng với các ví dụ về SO. – ceving