微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

clojure 对任何关于命名约定fns的作品都是开放的,尤其是将类泛型 fns 作为部分

如何解决clojure 对任何关于命名约定fns的作品都是开放的,尤其是将类泛型 fns 作为部分

我对函数式编程和 clojure 很陌生。我喜欢。 我想知道社区对遵循 fn 命名方法的看法: 使用这种命名是一种可行的方法,还是出于某种原因需要避免?

示例:

(defn coll<spec>?
  "Checks wether the given thing is a collection of elements of ::spec-type"
  [spec-type thing]
  (and (coll? thing)
       (every? #(spec/valid? spec-type %)
               thing)))

(defn coll<spec>?nil
  "Checks if the given thing is a collection of elements of ::spec-type or nil"
  [spec-type thing]
  (or (nil? thing)
      (coll<spec>? spec-type thing)))

现在...在其他地方我正在 clojure defrecrod/specs 中使用部分应用程序... 类似这样:

; somewhere inside a defrecord
^{:spec (partial p?/coll<spec>?nil ::widgets)} widgets component-widgets

现在,我为 colls、sets、hash-maps 创建了这个,它有一个类似泛型的规范形式(规范/有效的内部应用?...),并直接应用谓词,分别用一个

代替

目前我正在与我的同事讨论这是否是一种体面、有意义和有用的方法 - 因为在 clojure 中命名这样的函数至少是有效的 - 或者社区是否认为这是不可行的。

我非常希望您对此发表有教益的意见。

解决方法

这是一个奇怪的命名约定,但很多项目都使用奇怪的命名约定,因为他们的作者相信它们会有所帮助。我想如果我读了你的代码库,变量命名约定可能不是最让我惊讶的事情。这不是侮辱:每个项目都有一些让我感到惊讶的东西。

但我完全不明白您为什么需要这些特定功能。正如肖恩·科菲尔德 (Sean Corfield) 在评论中所说,有很好的规范组合器函数可以从更简单的规范中构建出更好的规范。您可以将 coll<spec>?s/valid? 结合起来,而不是写 s/coll-of

(s/valid? (s/coll-of spec-type) thing)

同样,您可以使用 s/ornil? 来想出 coll<spec>?nil

(s/valid? (s/or nil? (s/coll-of spec-type) thing))

这显然比在每个呼叫站点上写的要多得多,而不仅仅是 coll<spec>?nil,因此您可以不理会我的建议。但关键是您可以提取用于定义这些规范的函数,并使用这些规范。

(defn nil-or-coll-of [spec]
  (s/or nil? (s/coll-of spec)))

(s/valid? (nil-or-coll-of spec-type) thing)

重要的是,这意味着您可以将 nil-or-coll-of 的结果传递给其他需要规范的函数,也许是从中构建更大的规范,或者尝试使其符合规范。如果您的所有函数都包含 s/valid?,您就不能这样做。

从组合通用函数的角度考虑,而不是为您想做的每件事从头开始定义一个新函数。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。