在 clojure 中,您可以将函数映射到值序列。是否有一个内置函数可以将单个值作为参数映射到一系列函数?
(map inc [1 2 3 4])
; -> (2 3 4 5)
(reverse-map [inc dec str] 1)
; -> (2 0 "1")
(reverse-map [str namespace name] :foo/bar/baz)
; -> (":foo/bar/baz" "foo/bar" "baz")
在 clojure 中,您可以将函数映射到值序列。是否有一个内置函数可以将单个值作为参数映射到一系列函数?
(map inc [1 2 3 4])
; -> (2 3 4 5)
(reverse-map [inc dec str] 1)
; -> (2 0 "1")
(reverse-map [str namespace name] :foo/bar/baz)
; -> (":foo/bar/baz" "foo/bar" "baz")
有juxt
一点类似。它接受许多函数并返回一个,将其参数传递给每个函数并返回一个返回值向量。所以:
> ((apply juxt [inc dec str]) 1)
[2 0 "1"]
主要区别在于它创建了一个向量,当然是急切的(即不懒惰)。原始map
创建的序列是懒惰的。
juxt
也适用于具有超过 1 个参数的函数:
> ((apply juxt [* / -]) 6 2)
[12 3 4]
不确定是否有,但它很容易实现:
(def reverse-map (fn [l value] (map #(% value) l)))
如果不需要懒惰,我会说使用并列,特别是因为它的作曲能力。但是,使用 map 和 repeat 的多元函数的反向映射的简单版本,两者都是惰性的,看起来像这样:
(defn reverse-map
[fcoll & args]
(map apply fcoll (repeat args)))
=> (reverse-map [inc dec str] 1)
(2 0 "1")
=> (reverse-map [* / -] 6 2)
(12 3 4)
好的,只是提出一个想法,这是一个具有与 juxt 相同的可组合性的版本。它甚至看起来很懒惰!
(defn lazy-juxt
[& funs]
(fn [& args]
(map apply funs (repeat args))))
=> ((juxt inc dec str) 1)
[2 0 "1"]
=> ((lazy-juxt inc dec str) 1)
(2 0 "1")
=> ((juxt * / -) 6 2)
[12 3 4]
=> ((lazy-juxt * / -) 6 2)
(12 3 4)