在Clojure中构建匿名函数的映射

时间:2016-06-09 19:18:33

标签: clojure

我只是在学习语言而且我有一个简单的问题。为什么这样做(构造{:key "value"}):

(#(assoc {} :key %) "value")

但这并不是:

(#({:key %}) "value")
ArityException Wrong number of args (0) passed to: PersistentArrayMap  clojure.lang.AFn.throwArity (AFn.java:429)

在Python上,后一种语法完全有效:

> (lambda v: {'key': v})('value')
{'key': 'value'}

编辑:感谢您提供了很好的答案,显然我需要不再将#视为与Python中的lambda等效。

3 个答案:

答案 0 :(得分:6)

#(f %)由读者扩展为(fn [%] (f %)。同样,#({:key %})也会扩展为(fn [%] ({:key %})。与此类似的python将是lambda v: {'key': v}(),它与Clojure版本具有完全相同的问题。

您要找的是等同于(fn [v] {:key v})的东西。如果您确实想使用#(...)表示法,可以使用#(do {:key %})

顺便说一句,我个人从不使用#(...)。我认为这很难(例如这个证据的例子),并且只比同等的fn形式更紧凑。然后还有#(...)形式无法嵌套的限制。

答案 1 :(得分:4)

这是#()读者的限制。 fn可以正常使用。

user=> ((fn [x] {:key x}) "value")
{:key "value"}

请查看文档Anonymous function literal (#())

答案 2 :(得分:0)

{:key %}是PersistentArrayMap。你有"动词位置"在你的函数调用中。你需要一种类型的Clojure方法来避免这种错误,正如你在第一个(工作)例子中看到的那样。