在Clojure中,有几种功能组合选项。有以下组合功能:
然而,AFAIK没有包含分支的组合功能。是否有任何函数以分支方式组成函数,如if
或cond
的函数版本?
当然,if版本很容易制作(虽然这种实现可能不是最快的):
(defn iff
([pred rtrue] (iff pred rtrue identity))
([pred rtrue rfalse]
(fn [& args]
(if (apply pred args)
(apply rtrue args)
(apply rfalse args)))))
默认情况下可以讨论在'else'案例中返回身份是正确的选择,或者在这种情况下是否应该返回nil。
使用此类函数可以生成更易于阅读的代码。而不是#(if (string? %) (trim %) %)
它将成为(iff string? trim)
,或者使用cond版本:
(condf string? trim,
vector? (partial apply str),
:else identity)
其他FP语言是否有这样的结构?我可以想象它在使用comp和juxt的作品中可能会很方便。为什么没有Clojure?
好的iff / condf实现的奖励积分:)
答案 0 :(得分:2)
我不确定这是否与您正在寻找的东西直接匹配(问题,对我来说,有些模糊),但你应该研究Monads和Arrows。
Monads允许您将函数与特定的“绑定”函数链接在一起,该函数定义了如何链接它们。它可以执行某种if / else流水线操作,如在Maybe和Either monad中,或者它可以模拟状态,就像State monad一样。
Monads内置于Haskell(作为monad)和F#(作为“Workflows”)。我见过Clojure的monad库(check this out for one),也可能有Arrow库。
答案 1 :(得分:1)
这接近战略规划的想法。您可以找到以下感兴趣的论文
战略规划的本质 RalfLämmel和Eelco Visser以及Joost Visser
http://homepages.cwi.nl/~ralf/eosp/
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.20.1969
答案 2 :(得分:1)
那么你可以提出很多这样的构图模式,并问为什么这不是核心语言。原因很明显,这是不可行的。该语言的核心为您提供了构建此类模式的所有构造。这些特征更像是contrib
类的东西,而不是语言的核心。
就实施而言,它将如下所示简单:
(defn condf [& args]
(let [chain (partition 2 args)]
(fn [& params]
(first (for [[p f] chain :when (or (= :else p) (apply p params))]
(apply f params))))))
(def my-func (condf string? clojure.string/trim
vector? (partial apply str)
:else identity))
(my-func "Ankur ") ==> "Ankur"
(my-func [1 2 3]) ==> "123"
(my-func '(1 2 3)) ==> (1 2 3)