这是一个关于Clojure中等效的Haskell移动平均函数的问题。

3

尝试理解Clojure和Haskell之间的区别。我有下面这段代码,用于计算时间序列数字列表的移动平均值:

movavg n []     = []
movavg n (x:xs) = map (/ n') sums
    where
        sums = scanl (+) (n' * x) $ zipWith (-) xs (replicate n x ++ xs)
        n'   = fromIntegral n

这在Clojure中的惯��版本是什么?

1
这个是否等价?https://dev59.com/rHM_5IYBdhLWcg3wlEFH#1320425 - Jonas
1
不,不是从效率方面来说的。区别在于消除冗余计算的方式。 - user1002430
我无法让Haskell代码正常工作,你能提供一个简单的例子,在其中调用movavg吗? - Jonas
1个回答

4

我认为这段话非常适合进行逐字翻译,这样的翻译也可以很地道,即:

(defn movavg [n coll]
  (when-let [[x & xs] (seq coll)]
    (map #(/ % n)
         (reductions + (* n x)
                     (map - xs (concat (repeat n x) xs))))))

特别是具有大量顺序功能的代码,由于它们是惰性的,因此始终存在接近Haskell的潜力。

编辑:根据Justin Kramer的建议缩短了代码。


2
(if (empty? coll) nil (let [[x & xs] coll] ...)) 可以缩短为 (when-let [[x & xs] (seq coll)] ...) - Justin Kramer
@JustinKramer:谢谢,我相应地修改了我的回答。 - Rörd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接