5

我还在学习这种外星人的功能范式......

我将如何在 Clojure 中以一种功能性的方式编写以下代码?假设这个缺失的部分是在别处定义的,并且行为如评论中所述。这是我熟悉的Python。

usernames = []
# just the usernames of all the connections I want to open.
cancelfunctions = {}
# this global contains anonymous functions to cancel connections, keyed by username

def cancelAll():
    for cancel in cancelfunctions.values():
        cancel()

def reopenAll():
    cancelfunctions = {}
    for name in usernames:
        # should return a function to close the connection and put it in the dict.
        cancelfunctions[name] = openConnection()

我真正需要知道的是如何建立一个新的回调字典,就像在reopenAll函数中一样,但是我在这里包含了更多的上下文,因为我可能会犯某种功能范式暴行,你会最可能想要修复整个程序。:)

4

2 回答 2

6

在 Clojure 中构建数据结构通常涉及reduce,它将一系列输入提供给累积最终返回值的函数。这里有两种编写函数的方法,该函数构造用户名到返回值的映射(即字典)open-connection

;; Using reduce directly
(defn reopen-all [usernames]
  (reduce
   (fn [m name] (assoc m name (open-connection)))
   {} usernames))

;; Using into, which uses reduce under the hood
(defn reopen-all [usernames]
  (into {} (for [name usernames]
             [name (open-connection)])))

请注意,这两个函数返回一个值并且不会像 Python 代码那样改变全局状态。全局状态本身并不坏,但将值生成与状态操作分开是件好事。对于状态,您可能需要一个atom

(def usernames [...])
(def cancel-fns (atom nil))

(defn init []
  (reset! cancel-fns (reopen-all usernames)))

cancel-all为了完整起见,这里是:

(defn cancel-all []
  (doseq [cancel-fn (vals @canel-fns)]
    (cancel-fn)))
于 2012-08-13T19:48:33.547 回答
2

这是python中的一种功能方法:

def reopen(usernames):
    return dict((name, openConnection()) for name in usernames)

在尝试使用主要的函数式语言之前,您可能会发现在 python 中“翻译”为函数式样式更容易。

于 2012-08-13T20:04:19.697 回答