如何在clojure中使用地图功能?

How to use map function in clojure?

我有一个名为 f 的函数,它应该映射到我的主函数中的一个向量上。但是,当我 lein run 我的代码没有任何反应时...

(ns my-proj.core
  (:gen-class))

(def f
  (fn
    [x]
    (println x)))

(def -main
  (fn
    [& args]
    (map f args)))

(-main [1 2 3 4 5])

根据 docs,代码似乎是正确的。但是我错过了什么?请帮助。

因为 map is lazy, you'll need to use a different approach if you want side effects. In this case, you could use run!:

(run! println [1 2 3 4 5])
;; 1
;; 2
;; 3
;; 4
;; 5
;;=> nil

您的函数 f 正在 returning nil 因为 println returns nil。函数 identity returns 是它被赋予的值。在这里,我注释掉了您的 println 调用,以便 f 有效地变为 identity:

(def f
  (fn
    [x]
    ;(println x)
    x
    ))

(defn -main [& args]
  (apply map f args))

(defn so []
  (-main [1 2 3 4 5])) 

要测试上面的内容,只需调用 (so)。我添加了 apply 来摆脱结果的双重包装。您可以用 identity 代替上述对 f 的调用(即 (apply map identity args))。

如果您确实想要 println 和 return 一个值,您也可以这样做:

(defn probe
  ([x]
   (println x)
   x)
  ([x msg]
    (println msg x)
    x))

只需调用 probe 而不是 fidentity(即 (apply map probe args))。 probe 是一个副作用 identity 函数,副作用是打印 return 值。

作为旁注,如果您确实怀疑是懒惰导致了问题,那么请将 return 值包装在 seq 中,或者使用 mapv 而不是 map .

我的代码不正确,对于初学者来说,我不应该将向量传递到 main 中;然后我所要做的就是添加 doall。如果您还需要 map 工作,这就是我想要的。

(ns my-proj.core
  (:gen-class))

(defn f
  [x]
  (println (+ x 1)))

(defn -main
  [& args]
  (doall
    (map f args)))

(-main 1 2 3 4 5)

我认为发生的情况是:向量将作为单个参数传递,因此如果您添加 doallmap 将起作用,但它只会将您的向量作为一个东西打印出来。我以为它会被地图解开。

您的代码有几个问题:

  1. -main 是可变的,可变变量 (args) 是您传递给 map 的变量。但是您将 -main 称为 (-main [1 2 3 4 5])。所以 args 将是 ([1 2 3 4 5])。所以你 map 不是在向量上,而是在包含向量的序列上。

    要么定义 -main 接受单个参数,要么将 -main 调用为 (-main 1 2 3 4 5)

  2. 你犯了混合副作用和懒惰的经典错误。有时这很有用,但通常是错误的。在你的情况下,这是一个错误——什么都不会发生,因为你永远不会意识到任何值(它们都是 nil,但 println 至少会作为副作用执行) .

    您可以通过 do-all. However, since the result is a sequence of nils, you are really only interested in performing the side-effects rather than the actual values produced. So dorun probably makes more sense. But the most idiomatic way would be to use doseq instead of map. doseq is similar to for 强制序列(这在逻辑上基本上等同于 map 周围的一些语法糖),除了 doseq 而不是 懒惰并且不产生序列——它纯粹是为了副作用。