Trên thực tế, (foldl.foldr) f z xs === foldr f z (concat $ reverse xs)
.
Ngay cả khi f
là một hoạt động liên kết, trình tự chính xác của các ứng dụng quan trọng vì nó có thể có tác động đến hiệu suất.
Chúng tôi bắt đầu với
(foldl.foldr) f z xs
foldl (foldr f) z xs
bằng văn bản với g = foldr f
và [x1,x2,...,xn_1,xn] = xs
trong một khoảnh khắc, đây là
(...((z `g` x1) `g` x2) ... `g` xn)
(`g` xn) ((`g` xn_1) ... ((`g` x1) z) ...)
foldr f z $ concat [xn,xn_1, ..., x1]
foldr f z $ concat $ reverse xs
Vì vậy, trong trường hợp của bạn chuỗi giảm đúng
(foldl.foldr) 1 [[1,2,3],[4,5,6]]
4+(5+(6+( 1+(2+(3+ 1)))))
22
Để wit ,
Prelude> (foldl.foldr) (:) [] [[1..3],[4..6],[7..8]]
[7,8,4,5,6,1,2,3]
Tương tự, (foldl.foldl) f z xs == foldl f z $ concat xs
. Với snoc a b = a++[b]
,
Prelude> (foldl.foldl) snoc [] [[1..3],[4..6],[7..8]]
[1,2,3,4,5,6,7,8]
Ngoài ra, (foldl.foldl.foldl) f z xs == (foldl.foldl) (foldl f) z xs == foldl (foldl f) z $ concat xs == (foldl.foldl) f z $ concat xs == foldl f z $ concat (concat xs)
, v.v .:
Prelude> (foldl.foldl.foldl) snoc [] [[[1..3],[4..6]],[[7..8]]]
[1,2,3,4,5,6,7,8]
Prelude> (foldl.foldr.foldl) snoc [] [[[1..3],[4..6]],[[7..8]]]
[7,8,1,2,3,4,5,6]
Prelude> (foldl.foldl.foldr) (:) [] [[[1..3],[4..6]],[[7..8]]]
[7,8,4,5,6,1,2,3]
Tôi không nghĩ rằng đây là đúng trình tự của các ứng dụng, Daniel. '7' sẽ không bị ép ngay khi bạn trình diễn, IMO. –
Có, nó sẽ - chặn tối ưu hóa - vẫn là một phần cho đến khi kết quả cuối cùng thunk được tạo ra bởi 'foldl' được đánh giá. Nhưng đánh giá nó sớm là ít để loại và làm cho nó dễ đọc hơn. –