如何在clojure中使用map函数?

时间:2016-11-25 00:54:13

标签: clojure functional-programming leiningen

我有一个名为f的函数,它应该映射到我的main函数中的向量上。但是当我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,代码似乎是正确的。但是我错过了什么? Plz帮助。

4 个答案:

答案 0 :(得分:1)

由于map是懒惰的,如果你想要副作用,你需要使用不同的方法。在这种情况下,您可以使用run!

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

答案 1 :(得分:0)

您的函数f正在返回nil,因为println会返回nil。函数identity返回给定的值。在此,我已对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并返回一个值,你也可以这样做:

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

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

作为旁注,如果您曾怀疑懒惰导致问题,请将返回值包装在seq中,或使用mapv代替map

答案 2 :(得分:0)

您的代码存在一些问题:

  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强制执行序列。但是,由于结果是nil s的序列,您实际上只对执行副作用而不是生成的实际值感兴趣。所以dorun可能更有意义。但最惯用的方法是使用doseq代替mapdoseq类似于for(基本上逻辑上等同于map周围的一些句法糖),除了doseq 懒惰且不产生一个序列 - 它纯粹是为了副作用。

答案 3 :(得分:-1)

我的代码不正确,对于初学者我不应该将一个向量传递给主;那么我所要做的就是添加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将起作用,但它只会打印出您的向量。我以为它会被地图打开。