Clojure左侧折叠在哪里

Clojure左侧折叠在哪里,clojure,functional-programming,fold,Clojure,Functional Programming,Fold,clojure执行左折叠还是右折叠 我知道clojure.core中有一个新的库Reducer,但它不应该存在吗?clojure实现了一个名为reduce的左折叠 为什么没有正确的折叠 reduce和许多其他函数处理序列,它们是 可从左侧进入,但不能从右侧进入 新的减速机和传感器设计用于在不同可访问性的数据结构上使用关联函数 Clojure实现了一个名为reduce的左折叠 为什么没有正确的折叠 reduce和许多其他函数处理序列,它们是 可从左侧进入,但不能从右侧进入 新的减速机和传感

clojure执行左折叠还是右折叠


我知道clojure.core中有一个新的库Reducer,但它不应该存在吗?

clojure实现了一个名为
reduce
的左折叠

为什么没有正确的折叠

  • reduce
    和许多其他函数处理序列,它们是 可从左侧进入,但不能从右侧进入

新的减速机和传感器设计用于在不同可访问性的数据结构上使用关联函数

Clojure实现了一个名为
reduce
的左折叠

为什么没有正确的折叠

  • reduce
    和许多其他函数处理序列,它们是 可从左侧进入,但不能从右侧进入

新的减速机和传感器设计用于在不同可访问性的数据结构上使用关联函数

正如缩略图所指出的,在jvm上不能有效地为序列实现reduce right。但事实证明,我们确实有一系列数据类型,可以从右侧进行有效的查找和截断。可以对向量实现reduce-right

user> 
(defn reduce-right
  [f init vec]
  (loop [acc init v vec]
    (if (empty? v)
      acc
      (recur (f acc (peek v)) (pop v)))))

#'user/reduce-right
user> (count (str (reduce-right *' 1 (into [] (range 1 100000))))) ; digit count
456569

正如缩略图所指出的,对于序列,reduce-right不能在jvm上有效地实现。但事实证明,我们确实有一系列数据类型,可以从右侧进行有效的查找和截断。可以对向量实现reduce-right

user> 
(defn reduce-right
  [f init vec]
  (loop [acc init v vec]
    (if (empty? v)
      acc
      (recur (f acc (peek v)) (pop v)))))

#'user/reduce-right
user> (count (str (reduce-right *' 1 (into [] (range 1 100000))))) ; digit count
456569

实现右折叠不需要从右边访问序列:
(defn reduce right[f init xs](if let[xs(seq xs)](f(first xs)(reduce right(rest xs)f init))init))
@sepp2k是的,您可以通过这种方式实现右折叠,但是JVM和Clojure的堆栈空间相当有限,无法处理长序列中的递归。例如,
(reduce right max-1(范围10000))
在此处导致堆栈溢出-YMMV。[为了得到这个结果,我修改了您的函数以一致地调用自己,并借此机会对其进行了一点简化:
(defn reduce right[f init xs](if(seq xs)(f(first xs)(reduce right f init(lazy seq(rest xs)))init))
)您不需要从右侧访问序列来实现右折叠:
(defn reduce right[f init xs](如果让[xs(seq xs)](f(first xs)(reduce right(rest xs)f init))init)
@sepp2k是的,您可以用这种方式实现右折叠,但是JVM和Clojure由于堆栈空间相当有限,无法处理长序列中的递归。例如,
(reduce right max-1(范围10000))
在这里导致堆栈溢出-YMMV。[为了得到这个结果,我修改了您的函数以一致地调用自己,并借此机会将其简化一点:
(defn reduce right[f init xs](if(seq xs)(f(first xs)(reduce right f init(lazy seq(rest xs)))init))
]根据
peek
pop
操作的位置,这在向量上做右折叠,但在列表上做左折叠:
(右减(fn[\ux]x):init(vec(范围10))
=>
0
(右减(fn[\ux]x):init(应用列表(范围10)))
=>
9
。是的,根本不是指列表。我想可以调用一个先决条件。根据
peek
pop
的操作,这在向量上做右折叠,但在列表上做左折叠:
(右减(fn[\ux]x):init(vec(范围10))
0
(右减(fn[\ux]x):init(应用列表(范围10))
=>
9
。是的,根本不适用于列表。我想可能需要先决条件。