如何在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
而不是 f
或 identity
(即 (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)
我认为发生的情况是:向量将作为单个参数传递,因此如果您添加 doall
,map
将起作用,但它只会将您的向量作为一个东西打印出来。我以为它会被地图解开。
您的代码有几个问题:
-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)
。
你犯了混合副作用和懒惰的经典错误。有时这很有用,但通常是错误的。在你的情况下,这是一个错误——什么都不会发生,因为你永远不会意识到任何值(它们都是 nil
,但 println
至少会作为副作用执行) .
您可以通过 do-all
. However, since the result is a sequence of nil
s, 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
是 而不是 懒惰并且不产生序列——它纯粹是为了副作用。
我有一个名为 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
而不是 f
或 identity
(即 (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)
我认为发生的情况是:向量将作为单个参数传递,因此如果您添加 doall
,map
将起作用,但它只会将您的向量作为一个东西打印出来。我以为它会被地图解开。
您的代码有几个问题:
-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)
。你犯了混合副作用和懒惰的经典错误。有时这很有用,但通常是错误的。在你的情况下,这是一个错误——什么都不会发生,因为你永远不会意识到任何值(它们都是
nil
,但println
至少会作为副作用执行) .您可以通过
do-all
. However, since the result is a sequence ofnil
s, you are really only interested in performing the side-effects rather than the actual values produced. Sodorun
probably makes more sense. But the most idiomatic way would be to usedoseq
instead ofmap
.doseq
is similar tofor
强制序列(这在逻辑上基本上等同于map
周围的一些语法糖),除了doseq
是 而不是 懒惰并且不产生序列——它纯粹是为了副作用。