My question is pretty similar to this one: How to evaluate a sequence of impure functions in Clojure? but instead of impure functions, how can I evaluate sequence of pure functions and get the results as another sequence?
Let's assume we have a vector of functions like:
[#(str "a" "b") #(str "c" "d") #(str "e" "f")]
And we need an output like this:
("ab" "cd" "ef")
I've tried something similar to this:
(map eval [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
but it just returns a vector of function references.
There are multiple ways to do what you are asking. It depends on whether you want a lazy sequence or not (you probably want lazy given there are no side-effects, but you might want no-lazy if there's an intensive computation that you want to cache), or if you want a vector as output (the same as your input). I'll try to follow what you tried to do.
Your map with eval is doing the following with each fn:
user=> (eval #(str 1))
#<user$eval1332$fn__1333 user$eval1332$fn__1333@38747597>
But you want something like the following:
user=> (eval (#(str 1)))
"1"
You want eval to have the fn applied, that is: the fn should be the first element of a list. Let's put it in a list:
user=> (map (comp eval list) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")
Cool. But instead of eval, you probably want to use apply:
user=> (apply #(str 1))
; ArityException Wrong number of args (1)
Ups! It failed. apply doesn't have a 0-arity overload, but we can pass an empty list:
user=> (apply #(str 1) ())
"1"
Much better. Let's do it with map:
user=> (map #(apply % ()) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")
Or better yet, given your functions receive no arguments, you'd better do as suggested by @Magos:
user=> (map #(%) [#(str "a" "b") #(str "c" "d") #(str "e" "f")])
("ab" "cd" "ef")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With