3

我对函数式编程相当陌生。我以前的编程经验主要是 Java。

用函数式语言设计函数时,传递原语还是集合更好?由于我缺乏函数式语言的知识,我觉得我无法通过选择一种或另一种来看到影响。

在我看来,传递一个集合会产生更清晰和更直观的代码(例如,传递一个名为 person 的地图而不是 name、surname 等)。另一方面,这会创建集合结构的依赖关系。也许这仅取决于您必须从该地图中使用的信息量。不确定...

我意识到这是一个公开的讨论,但我主要关心的是是否有一种事实上的方法来设计功能。

更新1

让我们假设我们有我之前说的人图,我们想要 str 它的内容。我想我们会做类似的事情:

; 
(def person {:name "John" :surname "Doe"})

(defn str-person
  "Give the full name of a person"
  [person]
  (apply str (interpose ", " (map #(get-in person [%]) [:surname :name]))))
; => Doe, John

; primitive alt
(defn str-person
  "Give the full name of a person"
  [name surname]
  (str surname ", " name))
; => Doe, John

现在,我相信第一个解决方案更接近 FP 的含义,并且可以扩展等,但另一方面,它似乎有点矫枉过正。

4

3 回答 3

2

仅从实用性的角度来看,我更喜欢传递集合和地图。您可以将一个非常复杂的数据结构放在一个映射中,并将其作为单个参数传递。这比将数据位作为单独的参数传递更容易。这不仅仅适用于函数式语言——同样的推理也可以应用于过程式或面向对象的语言。

于 2013-06-25T18:54:32.990 回答
2

在 Clojure 中,由于您的域是在哈希映射等数据结构中建模的,因此您的工作主要通过映射函数和对这些数据结构的转换来表示。

因此,我发现我的应用程序的高级域级表达式通常定义为:

(map process-thing things)

例如,这是我们作为服务部署的超赞推文处理器应用程序的核心:

;; Get tweets from twitter
(def tweets [{:username "max"
              :text "I'm tweeting."}
             {:username "kate"
              :text "I ate breakfast."}])

(defn capitalize-tweet [{:keys [text] :as tweet}]
  (let [processed-text (clojure.string/upper-case text)]
    (assoc tweet :text processed-text)))

(map capitalize-tweet tweets)
;=> ({:text "I'M TWEETING.", :username "max"} 
;    {:text "I ATE BREAKFAST.", :username "kate"})

如果我需要完成更多处理,或者如果我的推文处理器的范围扩大,我发现推理我的应用程序的最简单方法是引入更多process-tweet功能并将它们链接到一个工作流中:

(map (comp do-something-else do-something capitalize-tweet) tweets)

我的三个处理函数接受一条推文并可能以不同的方式对其进行解构,并且它们可能与像 Do One Thing 这样的较小函数协作clojure.string/upper-case,但这些都是实现细节。

较小的函数和库调用被缝合在一起,以服务于通过管道发送推文的更广泛目标,这些小函数构成了我用来表达该管道的更高级别的推文处理函数。

这通常是我喜欢用 Clojure 处理问题的方式,它使我的代码组织起来很容易。这些对原语进行操作的小函数组成了 functionA,而这些其他小函数组成了 functionB,其中 functionA 和 B 对我程序的核心数据结构进行操作。

再举一个例子,看看 Ring ( https://github.com/ring-clojure/ring/wiki/Concepts )。一个请求哈希映射进来,通过定义您的应用程序的处理程序(以及转换处理程序的中间件函数!)进行转换,然后出现一个响应哈希映射。

于 2013-06-25T23:02:51.467 回答
0

这取决于用例。

我不认为 FP “更喜欢”其中一个,只要你传递不可变的结构,否则你就有失去FP 几乎建立在其上的referential-transparency的风险。

于 2013-06-25T17:07:33.327 回答