Java类的Clojure中的多态性实现接口 - 包装器写作



我在编写Clojure中的一些代码中间,这在很大程度上依赖于Apache Commons Math3库中的某些功能。我以前从未编写过任何Java代码,并且正在尝试提出一种优雅的解决方案来创建一些我经常使用的Clojure包装器。希望尽管不是真正成为OOP或Java专家,但我将能够传达我试图做的事情。我将用一个具体的简单示例来描述挑战

一般而言,我有一个Java类的集合,这些类都从给定的接口继承了一些方法。要举一个具体示例,请考虑分布包。有3个接口,其中一个是重新分布。继承重新分布接口的类可以访问某些方法,例如"密度"。

在Clojure我可以做

(.density (new NormalDistribution 0 1) 2)
(.density (new ExponentialDistribution 1) 2)

目的是编写一个多态函数"密度",该功能在不同的分布上派遣,本身Java类。

我可以编写协议,称其为密度 - eval

(defprotocol density-eval
  (density [distribution x]))

并手动扩展每个分布

(extend-type NormalDistribution
  density-eval
  (density [d x] (.density d x)))

但是,我需要为每个分布做到这一点...并且其中很多...代码对于每个分布都是相同的。

为了节省时间,我想做的就是扩展一些更通用的东西...例如,正常分布的父母类型,但我不知道从这里去哪里。我目前拥有的是

(extend-type RealDistribution
  density-eval
  (density [d x] (.density d x)))

重新分布是正常分布和实现的接口。这起作用...然后,我可以为实现重新分布接口的许多分布y致电(密度y x)。例如(密度(新的常规分布0 1)0)0)工作正常。但是,问题在于我为实现IntegerDistribution接口的类玩了同一游戏。我定义了一个新协议

(defprotocol pmf-eval
  (pmf [distribution x]))
(extend-type IntegerDistribution
  pmf-eval
  (pmf [d x] (.probability d x)))

,然后对于实现IntegerDistribution接口的类,我可以做(PMF(PMF(新Poissondistribution 3)2)2),并且可以很好地工作...但是,我再也无法在分布y上拨打(密度y x)重新分布接口。我有错误:

    1. Unhandled java.lang.IllegalArgumentException
   No implementation of method: :density of protocol:
   #'distributions.core/density-eval found for class:
   org.apache.commons.math3.distribution.NormalDistribution

当我以某种方式在repl中执行第二个协议代码时,它会干扰第一个。

最终,我想为这些类的方法编写多态性包装器功能,但我不知道如何尽可能简单明了。请告知...

您编写的内容应该没问题,尽管如果有任何类两个接口的类,您会遇到麻烦。

为什么您说这不适合您:您确定吗?IntegerDistribution实际上没有density参数,您的错误消息显示您实际上定义了一个名为univariate-integer而不是density-eval的协议,因此我想知道您在尝试简化并隔离堆栈溢出问题时是否遇到了错误。

最新更新