gpt4 book ai didi

clojure - 是否可以在 arity 上重载 Clojure 多方法?

转载 作者:行者123 更新时间:2023-12-03 13:31:54 25 4
gpt4 key购买 nike

例如,我有一些使用多方法的代码,理想情况下希望重载函数(在本例中为多功能),以便我可以传递更高阶的函数来帮助进行测试。

这是示例:

(ns multi)

(defn my-print [m] (println "The colour is" (:colour m)))

(defmulti which-colour-mm (fn [m f] (:colour m)))

(defmethod which-colour-mm :blue [m f] (f m))
(defmethod which-colour-mm :red [m f] (f m))
(defmethod which-colour-mm :default [m f] (println "Default: Neither Blue nor Red"))

(defn which-colour
([m] (which-colour-mm m my-print))
([m f] (which-colour-mm m f)))

(which-colour {:colour :blue :object :ball})
(which-colour {:colour :yellow :object :ball})
(which-colour {:colour :blue :animal :parrot} (fn [m] (println "The " (:animal m) "is" (:colour m))))

所以我的 defn 提供了 arity 重载,但我想知道 defmethod 是否支持这样的东西。 (我猜你不想为每个 defmethod 声明都这样做。)

这是最合适的(我敢说,惯用的)方法,还是有更好的方法?

最佳答案

这很好。有库的“用户”界面和“类型”界面。它们可能相同,但不必相同。

“用户”界面在您的情况下是 which-colour . “类型”接口(interface)是which-colour-mm (好吧,不是真的,只是为了争论)。您库的用户不需要了解多方法。

另一方面,有人提供了一种新颜色——比如 :purple - 不必关心多参数样板。这是在 which-colour 中为他处理的.

这是一个完全有效的设计!

但当然有一个价格标签:假设你有一种颜色,它有一些更高效的方式来做事......现在,你被锁定在一个可能较慢的界面中。

稍微澄清一下:假设您有一个集合接口(interface)。您提供一个函数 - conj - 允许用户向集合中添加元素。它是这样实现的:

(defn conj
[coll & elements]
(reduce conj1 coll elements))
conj1是“类型”接口(interface)(例如,多方法或协议(protocol)函数):它将一个元素添加到集合中。因此,提供新集合类型的人只需实现添加单个参数的简单案例。并且自动地,新类型也将支持添加多个元素。

但是现在假设您有一个集合类型,它允许以一种比一个接一个地添加更快的方式添加多个元素。现在无法使用此功能。

因此,您将多方法/协议(protocol)函数设为函数 conj本身。现在集合可以使用更快的方式。但是每个实现都必须提供多个元素样板。

这是一个权衡,取决于您的决定。没有正确的方式(tm)。两者都可以被认为是惯用的。 (尽管我个人会尽可能多地尝试第一个。)

YMMV。

编辑:在调度值中没有编码的多参数方法示例。
(defmulti which-colour-mm (fn [m & args] (:colour m)))
(defmethod which-colour-mm :blue
([m] (print m))
([m f] (f m)))

关于clojure - 是否可以在 arity 上重载 Clojure 多方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10313657/

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