首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用匿名函数宏时的映射错误

使用匿名函数宏时的映射错误
EN

Stack Overflow用户
提问于 2020-07-20 15:58:55
回答 2查看 95关注 0票数 0

为什么这样做:

代码语言:javascript
复制
(mapcat (fn [x] x) [[1] [2 3] [[4 5 6]]])

但这会导致一个错误?

代码语言:javascript
复制
(mapcat #(%) [[1] [2 3] [[4 5 6]]])

错误是:

ArityException错误数目的args (0)传递给: PersistentVector clojure.lang.AFn.throwArity (AFn.java:429)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-20 17:08:08

#(%)等同于(fn [x] (x)),而不是(fn [x] x)。这是问题的核心。每当您不确定特定的读取器语法做什么时,read-string就会非常方便。在您的REPL中尝试(read-string "#(%)")。它应该打印一些类似(fn* [p1__3#] (p1__3#))的东西。p1__3#是一个自由变量,从某种意义上说,我们可以用任何其他不限定的符号替换它,这将是等价的。

ArityException而言,向量可以称为函数。它们是它们索引的函数。例如,([:a :b :c] 1)返回:b。当被称为函数时,只有偶然性-1是合法的。在这种情况下,使用mapcatting和#(%)调用输入中的每个向量,不带任何参数。这就是导致ArityException的原因。

此外,(mapcat (fn [x] x) ...)(mapcat identity ...)相同,也与(apply concat ...)相同。你可能想用这个代替。

票数 4
EN

Stack Overflow用户

发布于 2020-07-20 16:00:23

你在寻找:

代码语言:javascript
复制
(mapcat #(identity %) [[1] [2 3] [[4 5 6]]])

这显示了进展情况:

代码语言:javascript
复制
(ns tst.demo.core
  (:use tupelo.core tupelo.test) )

(dotest
  (let [data [[1]
              [2 3]
              [[4 5 6]]]]
    (is= [1 2 3 [4 5 6]]
      (mapcat (fn [x] x) data)
      (mapcat (fn [x] (identity x)) data)
      (mapcat #(identity %) data))))

当您使用#(%)时,本质上是这样说的:

代码语言:javascript
复制
([2])     ; missing arg

以下是如何理解它

代码语言:javascript
复制
(dotest
  (let [data [0 1 2 3 4]]
    (is= 2 (get data 2))
    (is= 2 (data 2))
    (is= 2 ([0 1 2 3 4] 2))
    (throws? ([0 1 2 3 4]))))

在clojure中,看到像(xxxxx)这样的副词意味着“函数调用”。就像在Java中一样,看到xxxxx()意味着“函数调用”。Clojure 中的父类绝不意味着分组(我知道,这是一个很难摆脱的习惯!)

演示:

代码语言:javascript
复制
(dotest
  (let [the-answer-fn (fn [& args] 42)
        fn-identity   (fn [x] x)
        fn-caller     (fn [x] (x))]
    (is= 42 (the-answer-fn))
    (is= 3 (identity 3))
    (is= 3 (fn-identity 3))
    (is= 42 (fn-caller the-answer-fn))
    (is (fn? #(the-answer-fn))) ; it always returns a function
    (throws? (fn-caller 3))))

请注意,#(xxx)读取器宏只是对

代码语言:javascript
复制
(fn [] (xxx))

所以,它会召唤它的身体。作为内存辅助工具,只要假装#不存在就行了。剩下的部分显示了发生了什么。

另外,请记住,您正在返回一个包装(xxx)函数调用的新函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62999351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档