Clojure记录实施IFn是一种好习惯吗?

时间:2012-08-15 02:52:38

标签: function clojure functional-programming record

假设我有一个“类似函数”的记录,至少在某种意义上它表示可以应用于某些参数的操作。

我可以通过实现clojure.lang.IFn来实现它的功能,例如:

(defrecord Func [f x]
  clojure.lang.IFn
    (invoke [this arg]
      (f x arg))
    (applyTo [this args]
      (apply f x args)))

 ((->Func + 7) 1)
 => 8

(是的,我知道我刚刚重新实现了partial的劣质版......这只是一个例子:-))

是否将记录工具clojure.lang.IFn作为一种良好做法?

这种方法有任何陷阱吗?

2 个答案:

答案 0 :(得分:6)

我很惊讶它还没有。记录应该是"a complete implementation of a persistent map"。所以要回答你的问题,我希望它是一个函数的关键,因为地图是;其他任何事都会令人感到意外。

答案 1 :(得分:0)

我无法直接给出是/否的答案,但我可以分享我的经验。

我定义了一个实现 clojure.lang.IFn 的记录。实现 IFn 是为了让我轻松通过 REPL 环境进行测试。

该记录旨在成为一个 Job 类,它将由一个工作人员处理。因此,我还实现了另一个接口 java.lang.Runnable 和一个 run 函数。

当我真正将代码放入集成测试时,它抛出了异常。为什么?

worker 的逻辑是这样的:

  1. 检查 Job 类是否为 Callable 实例,如果是,则调用 call 函数。
  2. 检查 Job 类是否为 Runnable 实例,如果是,则调用 run 函数。

然而,clojure.lang.IFn 已经扩展了 CallableRunnable,因此引发了异常,因为我忘记实现 call 函数。