当前位置 : 主页 > 大数据 > 区块链 >

如何将Clojure协议扩展到另一个协议?

来源:互联网 收集:自由互联 发布时间:2021-06-22
假设我有两个协议: (defprotocol A (f [this]))(defprotocol B (g [x y])) 而且我想将协议B扩展到支持协议A的所有实例: (extend-protocol A String (f [this] (.length this)))(extend-protocol B user.A (g [x y] (* (f x) (
假设我有两个协议:

(defprotocol A 
  (f [this]))

(defprotocol B 
  (g [x y]))

而且我想将协议B扩展到支持协议A的所有实例:

(extend-protocol A 
  String 
    (f [this] (.length this)))

(extend-protocol B 
  user.A
    (g [x y] (* (f x) (f y))))

主要动机是避免将B扩展到所有可能扩展到A的可能类,或者甚至到其他人可能扩展到A的未知类别(例如,假设A是公共API的一部分) .

但是这不行 – 你得到如下的东西:

(g "abc" "abcd")
=> #<IllegalArgumentException java.lang.IllegalArgumentException: 
No implementation of method: :g of protocol: #'user/B found for 
class: java.lang.String>

这是可能的吗如果没有,是否有明智的解决方法来实现同样的目标?

在我看来,你可以用f来实现函数g.如果是这种情况,您需要没有协议B的所有多态.

我的意思是以下,因为f是多态的

(defn g [x y]
  (* (f x) (f y)))

产生支持实现协议A的所有类型的函数g.

通常,当协议位于最底层时,仅根据协议功能(或其他使用协议的其他功能)定义的简单功能使整个命名空间/库/程序非常多态,可扩展和灵活.

序列库是一个很好的例子.简化,有两个多态函数,第一个和其余.序列库的其余部分是普通函数.

网友评论