clojure - 您将如何在 Clojure 中为其他数据类型惯用地扩展算术函数?

标签 clojure protocols multimethod

所以我想用java.awt.Color对于某些事情,我希望能够编写这样的代码:

(use 'java.awt.Color)
(= Color/BLUE (- Color/WHITE Color/RED Color/GREEN))

查看 - 的核心实现,它专门谈论clojure.lang.Numbers ,这对我来说意味着我没有做任何事情来“ Hook ”核心实现并对其进行扩展。

在互联网上环顾四周,人们似乎在做两种不同的事情:
  • 自己写defn -函数,它只知道他们感兴趣的数据类型。要使用你可能最终会为命名空间添加前缀,例如:
    (= Color/BLUE (scdf.color/- Color/WHITE Color/RED Color/GREEN))
    或者use读取命名空间并使用 clojure.core/-当你想要数字数学时。
  • 将特殊情况编码到您的 -传递到 clojure.core/- 的实现当您的实现通过 Number .

  • 不幸的是,我不喜欢其中任何一个。第一个可能是最干净的,因为第二个假设您唯一关心的数学运算是它们的新数据类型和数字。

    我是 Clojure 的新手,但我们不应该在这里使用协议(protocol)或多方法,这样当人们创建/使用自定义类型时,他们可以“扩展”这些功能,让它们无缝工作吗? + 有什么原因吗? , -等不支持这个? (或者是吗?从我阅读代码来看,它们似乎不是,但也许我读错了)。

    如果我想为常见的现有函数编写自己的扩展,例如 +对于其他数据类型,我应该怎么做才能很好地与现有函数和可能的其他数据类型一起使用?

    最佳答案

    它并不是专门为此设计的,而是 core.matrix您可能会对这里感兴趣,原因如下:

  • 源代码提供了如何使用协议(protocol)来定义与各种不同类型一起使用的操作的示例。例如,(+ [1 2] [3 4]) => [4 6]) .值得研究如何做到这一点:基本上操作符是调用协议(protocol)的常规函数​​,每种数据类型通过 extend-protocol 提供协议(protocol)的实现。
  • 您可能有兴趣制作 java.awt.Color作为 core.matrix 实现工作(即作为 4D RGBA 向量)。我在这里用 BufferedImage 做了类似的事情:https://github.com/clojure-numerics/image-matrix .如果您实现了基本的 core.matrix 协议(protocol),那么您将获得整个 core.matrix API 来使用 Color对象。这将为您节省大量实现不同操作的工作。
  • 关于clojure - 您将如何在 Clojure 中为其他数据类型惯用地扩展算术函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16502968/

    相关文章:

    javascript - 如何从链接对话框中删除协议(protocol)(ckeditor)

    使用动态协议(protocol)类型的 Swift 动态类型初始化

    C++ 到 Objective-C,在 for 循环中使用 const int

    clojure - 方案-> Clojure : multimethods with predicates in the methods?

    clojure - Clojure 中的速率限制 core.async channel

    Clojure 清理内部减少

    clojure - 关于字符串来源的问题?

    macros - 如何在宏中定义变量,以便它们可供宏的调用者使用

    python - flask-restful 有一个 get/<id> 并在同一个类中用 json 发布

    clojure - 使用跨多个命名空间定义的 Clojure 多方法