繁体   English   中英

如何在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])

根据文档 ,代码似乎是正确的。 但是我想念什么? 请帮助。

由于map是懒惰的,因此如果需要副作用,则需要使用其他方法。 在这种情况下,您可以使用run!

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

您的函数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

您的代码有几个问题:

  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的序列,因此您实际上只对执行副作用感兴趣,而不是对产生的实际值感兴趣。 所以dorun可能更有意义。 但是,最惯用的方法是使用doseq而不是map doseq类似于for (这基本上是逻辑上等同于周围的一些语法糖map ),不同之处doseq 懒惰并且不产生的序列-它是纯粹为副作用。

我的代码不正确,对于初学者来说,我不应该将向量传递给主体。 然后我要做的就是添加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将起作用,但只会将向量打印为一件事。 我以为它将被地图解开。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM