记住一个参数

Memoize over one parameter

我有一个函数,它接受两个我想记住的输入。函数的输出仅取决于第一个输入的值,第二个输入的值对结果没有函数影响(但可能会影响完成所需的时间)。因为我不希望第二个参数影响记忆,所以我不能使用 memoize。有没有一种惯用的方法可以做到这一点,还是我必须自己实现记忆?

您可以将您的函数包装到另一个函数(带有一个参数)中,并使用第二个默认参数调用它。然后就可以记忆新功能了

(defn foo
  [param1]
  (baz param1 default-value))

我建议为此使用缓存(如 clojure.core.cache)而不是函数记忆:

(defonce result-cache
  (atom (cache/fifo-cache-factory {})))

(defn expensive-fun [n s]
  (println "Sleeping" s)
  (Thread/sleep s)
  (* n n))

(defn cached-fun [n s]
  (cache/lookup
    (swap! result-cache
           #(cache/through
              (fn [k] (expensive-fun k s))
              %
              n))
    n))

(cached-fun 111 500)
Sleeping 500
=> 12321
(cached-fun 111 600) ;; returns immediately regardless of 2nd arg
=> 12321
(cached-fun 123 600)
Sleeping 600
=> 15129

memoize 不支持仅对某些参数进行缓存,但您自己可以轻松实现:

(defn search* [a b]
  (* a b))

(def search
  (let [mem (atom {})]
    (fn [a b]
      (or (when-let [cached (get @mem a)]
            (println "retrieved from cache")
            cached)
          (let [ret (search* a b)]
            (println "storing in cache")
            (swap! mem assoc a ret)
            ret)))))