gpt4 book ai didi

Clojure/FP : apply functions to each argument to an operator

转载 作者:行者123 更新时间:2023-12-04 22:39:47 25 4
gpt4 key购买 nike

假设我有几个向量

(def coll-a [{:name "foo"} ...])
(def coll-b [{:name "foo"} ...])
(def coll-c [{:name "foo"} ...])

并且我想看看第一个元素的名称是否相等。

我可以
(= (:name (first coll-a)) (:name (first coll-b)) (:name (first coll-c)))

但是随着更多功能的组合,这很快就会变得很累并且过于冗长。 (也许我想比较第一个元素名称的最后一个字母?)

为了直接表达计算的本质,似乎很直观
(apply = (map (comp :name first) [coll-a coll-b coll-c]))

但这让我想知道这种事情是否有更高级别的抽象。

我经常发现自己比较/以其他方式操作要通过应用于多个元素的单个组合计算的事物,但 map 语法对我来说有点不合适。

如果我要自制某种运算符,我会想要这样的语法
(-op- (= :name first) coll-a coll-b coll-c)

因为大部分计算都用 (= :name first) 表示.

我想要一个抽象来应用于运算符和应用于每个参数的函数。也就是说,求和应该和比较一样容易。
(def coll-a [{:name "foo" :age 43}])
(def coll-b [{:name "foo" :age 35}])
(def coll-c [{:name "foo" :age 28}])

(-op- (+ :age first) coll-a coll-b coll-c)
; => 106
(-op- (= :name first) coll-a coll-b coll-c)
; => true

就像是
(defmacro -op- 
[[op & to-comp] & args]
(let [args' (map (fn [a] `((comp ~@to-comp) ~a)) args)]
`(~op ~@args')))
  • 在 clojure 中有没有一种惯用的方法可以做到这一点,我可以使用一些标准库函数?
  • 这种表达方式有名称吗?
  • 最佳答案

    对于您的加法示例,我经常使用 transduce :

    (transduce
    (map (comp :age first))
    +
    [coll-a coll-b coll-c])

    您的相等用例比较棘手,但您可以创建一个自定义的减少函数来维护类似的模式。这是一个这样的函数:
    (defn all? [f]
    (let [prev (volatile! ::no-value)]
    (fn
    ([] true)
    ([result] result)
    ([result item]
    (if (or (= ::no-value @prev)
    (f @prev item))
    (do
    (vreset! prev item)
    true)
    (reduced false))))))

    然后将其用作
    (transduce
    (map (comp :name first))
    (all? =)
    [coll-a coll-b coll-c])

    语义与您的 -op- 非常相似。宏,同时更符合 Clojure 的习惯和可扩展性。其他 Clojure 开发人员会立即了解您对 transduce 的使用情况.他们可能需要研究自定义的归约函数,但这些函数在 Clojure 中很常见,读者可以看到它如何适合现有模式。此外,如何为简单的 map-and-apply 不起作用的用例创建新的减少函数应该是相当透明的。转换函数也可以与其他转换组合,例如 filtermapcat ,适用于您有更复杂的初始数据结构的情况。

    关于Clojure/FP : apply functions to each argument to an operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51034374/

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