【问题标题】:Choosing function over another function Clojure选择函数而不是另一个函数 Clojure
【发布时间】:2015-07-02 09:23:12
【问题描述】:

我有一套这样的功能,

(defn nmf-kernel [a b])
(defn lin-kernel [a b])
(defn log-kernel [a b])

然后像这样的另一组初始化函数,

(defn fill-random 
  ([a b] "filling matrix random")
  ([a b c] "filling matrix random with another setting parameter"))

好的,我有一个场景:

(defn scenario 
   [kernel a b c d e f g]
   (let [init-fn (if (= kernel nmf-kernel)
                     (fill-random a b)
                     (fill-random a b c))))

问题:我怎样才能习惯性地选择一个函数而不是另一个函数?因为当我使用(if (= kernel nmf-kernel)) 时,感觉这种方法并不优雅。而且,当我有 10 个核函数和 10 种填充矩阵的方法时,我该如何设计这个场景?

PS:我在创建内核函数时遇到了同样的问题,但内核函数的答案可能是在 Clojure 中使用协议。

【问题讨论】:

  • 我想您可能正在寻找多种方法。
  • 什么是eval-kernel?我的印象是,scenariokernel 参数是您要评估的函数本身?或者它只是一个标志(例如一个符号或关键字)?如果后者使用= 与函数nmf-kernel 进行比较总是会失败。
  • @Vanessa 嗯,好的,我会检查 defmulti 来设计这些方法,感谢您的帮助:D eval-kernel 永远不存在,我已经编辑了帖子

标签: design-patterns clojure code-reuse


【解决方案1】:

如果我没看错的话,你有许多可能的内核函数,并且 - 对于每一个 - 对应的初始化函数

函数就是值,所以你可以做一个映射:

(def kernel->initialization {nmf-kernel (fn do-something [& _] "Hello")
                             lin-kernel (fn do-something-else [& _] "world!")
                             ; ...
                             })

...您可以使用它来选择适当的初始化:

((kernel->initialization nmf-kernel) "blah" "blah" "blah")
; => "Hello"

通常情况下,您会使用case form 来处理这类事情。但它不起作用 - 函数不是 case 为其键所需的 compile-time 文字。


如果您选择初始化函数的标准可能会变得更加复杂,那么多方法是可行的方法。但是对于仅在另一个功能的基础上选择一个功能来说,它们有点繁重。

【讨论】:

  • 唷,感谢您的帮助。 + 1 映射技术,我同意当我想选择某个函数时,多方法是如此沉重。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2019-09-02
相关资源
最近更新 更多