【问题标题】:Mapping logical function映射逻辑函数
【发布时间】:2013-11-14 11:44:47
【问题描述】:

我正在尝试使用地图和逻辑函数“和”来共同加入两个列表

(map and '(true false true) '(0 1 2))

我希望看到

(0 false 2)

而不是那个

CompilerException java.lang.RuntimeException: Can't take value of a macro:
#'clojure.core/and, compiling:(NO_SOURCE_PATH:274:1)

发生。

我该如何解决?

【问题讨论】:

  • user=> (apply and [true false]) CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compile:(NO_SOURCE_PATH:280: 1) 用户=> (应用 + [1 2]) 3

标签: clojure


【解决方案1】:

您可以将“and”宏包装到一个函数中

(map #(and % %2) '(true false true) '(0 1 2))

Result:(0 false 2)

map 函数不允许您使用宏作为第一个参数,所以这是解决问题的简单技巧

【讨论】:

    【解决方案2】:

    接受的答案绝对是可靠的,我只是想给你一个将宏转换为函数的示例(主要用于娱乐/学习目的):

    (defmacro to-fun [macro]       ;; converting a macro to a function 
      `#(eval (cons '~macro %&)))  ;; e.g. "eval"uated at run time vs. compile time, 
                                   ;; and hence can be composed
    

    现在我们可以用它包装一个(ny)宏:

    (map (to-fun and) [true false true] [0 1 2])
    (0 false 2) 
    

    或:

    (map (to-fun or) [true false true] [0 1 2])
    (true 1 true)
    

    【讨论】:

    • 非常感谢。那么问题是地图必须得到一个功能并且不能与宏一起使用?
    • 是的。 map 的第一个参数是一个函数。 map 做什么,它applies 这个函数到这些集合中的元素。为了使任何函数应用(读作“调用”),它需要有一个应用“方法”(在 Clojure 源代码中它被称为applyTo)。宏在编译时被评估,通常不是“函数”,而“其他东西”没有这样的“方法”(例如,不能应用)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 2020-09-28
    • 1970-01-01
    • 2020-10-21
    相关资源
    最近更新 更多