分支功能组成:if / cond的组成版本?

时间:2012-11-06 16:33:44

标签: clojure functional-programming

在Clojure中,有几种功能组合选项。有以下组合功能:

  • 申请:'展开'论点
  • 部分:对于尚未给出的参数
  • Comp:用于通过多种功能管道连续结果
  • Juxt:在多个函数上应用一个参数

然而,AFAIK没有包含分支的组合功能。是否有任何函数以分支方式组成函数,如ifcond的函数版本?

当然,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实现的奖励积分:)

3 个答案:

答案 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)