gpt4 book ai didi

用于 HashMap 的 Clojure DRY 模式?

转载 作者:行者123 更新时间:2023-12-04 16:50:57 26 4
gpt4 key购买 nike

我在 let 做了很多计算块,返回包含数据的哈希映射。下面是一个不那么简单的例子:

(def ground-truth
(let [n 201
t1 2.0
linspace (fn [a b n] (let [d (/ (- b a) (dec n))]
(map (fn [x] (+ a (* x d))) (range n))))
times (vec (linspace 0.0, t1, n))
wavelength 1
wavespeed 1
f (* (/ wavespeed wavelength) 2 Math/PI)
dt (- (get times 1) (get times 0))
amplitude 5.0
ground-level 10.0
h-true (mapv #(+ ground-level
(* amplitude (Math/sin (* f %))))
times)
h-dot-true (mapv #(* amplitude f (Math/cos (* f %)))
times)
baro-bias-true -3.777]
{:n n, :times times, :f f, :dt dt, :h-true h-true,
:h-dot-true h-dot-true, :baro-bias-true baro-bias-true}))

我想要做的是摆脱最终表达式中的重复。对于这个小例子来说,这不是什么大问题,但我有一些更长、更复杂的问题,重复使得修改表达式变得乏味且容易出错。

我试过这个宏:
(defmacro hashup [name-list]
`(into {}
(map vector
(mapv keyword ~name-list)
(mapv eval ~name-list))))

仅适用于 eval作品,适用于 vars :
(def foo 41) (def bar 42)
(hashup '[foo bar])

{:foo 41, :bar 42}



但不是在 let块:
(let [a 1, b (inc a)] (hashup '[a b]))

CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(null:1:1) Util.java: 221 clojure.lang.Util/runtimeException
core.clj: 3105 clojure.core$eval/invokeStatic



在查看以下 SO 问题后,如预期的那样: Variable scope + eval in Clojure , eval a list into a let on clojure

有人可能会说“好吧,您可以通过 let 在 namespace 中查找变量然后使用类似 def 之类的东西在 hashup 块之外重复,或者您可以在 let 块底部重复忘记宏魔法。但是在这个确切的用例中,没有办法不要重复自己。

我是不是错过了一个干掉这种代码的好方法?

最佳答案

尝试这个:

(defmacro ->hash [& vars]
(list `zipmap
(mapv keyword vars)
(vec vars)))

然后:
(->hash a b c) => {:a a :b b :c c}

它也适用于 let块。

关于用于 HashMap 的 Clojure DRY 模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45082383/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com