理解Clojure偏

时间:2014-03-27 18:05:23

标签: clojure

我正在阅读Clojure编程书。我是关于偏爱的一个例子,它是这样的:

(def only-strings (partial filter string?))

问题是,如果我写下一个函数:

(defn only-strings [x] (filter string? x))

我可以得到相同的结果:

user=> (only-strings [6 3 "hola" 45 54])
("hola")

在这里使用部分有什么好处?或者这个例子只是为了简单地展示它们?有人可以给我一个例子,其中一部分是有用的。非常感谢。

4 个答案:

答案 0 :(得分:9)

这最终归结为个人风格,你可以用匿名函数做部分事,尽管有时partial会使它更漂亮。将第一对参数应用于可变参数函数就是一个例子:

user> (def bigger+ (partial + 7 42)) 
#'user/bigger+
user> (bigger+ 1 2)
52

与之相比:

user> (def bigger+ (fn [& nums] (apply + 7 42 nums)))
#'user/bigger+
user> (bigger+ 1 2)
52

当然,如果你看起来更好,你可以自由选择第二个。

答案 1 :(得分:8)

在这种情况下partial的好处是你可以修复第一个参数并将其绑定到string?

甚至所有partial都是如此。正如你在亚瑟的例子中所看到的那样,预定义第一个参数。

(def foo (partial + 1 2))

(foo 3 4)    ; same as (+ 1 2 3 4)
;=> 10

在这种情况下,部分i将前两个参数绑定到12

为什么这会有用?

您可能希望在函数上使用mapapply,该函数有两个参数。这将是非常糟糕的,因为map和apply需要一个函数,需要一个参数。所以你可以修复第一个参数并为此使用partial,你得到一个只需要一个参数的新函数。因此它可以与map或apply一起使用。

在我的一个项目中,我有这个案例。我想过使用partial或匿名函数。因为我只在一个案例中需要它,所以我使用了lambda。但是如果你需要它不止一次,那么用partial定义一个新函数会非常有用。

答案 2 :(得分:1)

如果你想要一个关于部分函数如何有用的例子,那么在Java世界中有一个非常普遍的实例,其中Java和Spring重新创建了部分函数应用程序(尽管是以一种笨重的方式)。

假设您有一个在Spring中配置的单例组件FooService,它配置了单例范围,并且像BarDao一样注入了一些东西。 FooService有许多业务方法,如retrieveBarsForSomeReason()。

当应用程序启动时,它会读取实例化FooService的应用程序上下文,并将BarDao作为实例变量注入其中。稍后,应用程序调用FooService上的方法,并调用BarDao上的方法作为其工作的一部分。

所以这不是一个真实的对象,这里没有OO,服务对象上的方法基本上都是函数。注入状态,在本例中为BarDao,相当于使用partial绑定对象,因此您不必在以后的调用中包含它。

答案 3 :(得分:1)

这是一个例子: (参见DEFN和DEF之间的区别)

mysql (as by default it takes root user)
mysql -u root -p