【问题标题】:Understanding Clojure partial部分理解 Clojure
【发布时间】:2014-03-27 18:05:23
【问题描述】:

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

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

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

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

我可以得到相同的结果:

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

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

    这就是partial 所做的一切。如您在您和 Arthur 的示例中所见,预定义第一个参数。

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

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

    为什么这会有用?

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

    在我的一个项目中,我遇到了这种情况。我考虑过使用partial 或匿名函数。因为我只在一种情况下需要它,所以我使用了 lambda。但是,如果您不止一次需要它,那么使用 partial 定义一个新函数会非常有用。

    【讨论】:

      【解决方案2】:

      这最终归结为个人风格问题,你可以用匿名函数来做任何事情,尽管有时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
      

      当然,如果您觉得第二个更好,您可以随意选择第二个。

      【讨论】:

        【解决方案3】:

        这是一个例子: (看DEFN和DEF的区别)

        (defn addDomain [domain user] ( str user domain))   
        (def buildEmail (partial addDomain "@domain.com"))
        (buildEmail "info")  
        
        ;; "info@domain.com"
        

        【讨论】:

          【解决方案4】:

          如果您想了解偏函数如何有用的示例,可以参考 Java 世界中非常常见的真实示例,其中 Java 和 Spring 重新创建偏函数应用程序(尽管方式很笨拙)。

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

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

          所以这不是一个真实的对象,这里没有任何面向对象的事情,服务对象上的方法基本上是函数。注入状态,在此示例中为 BarDao,等效于使用 partial 绑定对象,因此您不必在以后的调用中包含它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-06
            • 1970-01-01
            • 2014-04-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多