Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying sequence of functions to a sequence of values

Tags:

clojure

I want to pairwise apply a list of functions to a list of values.

Here's an example to illustrate.

user=> (defn a [f x] (f x))
#'user/a
user=> (map a [inc dec] '(98 8))
(99 7)

Notice I had to define a function a that takes a function and applies it to a value. Basically abstracting function application.

Is there a more natural way to do this? I would really just like to use map with defining a helper function.

like image 409
yalis Avatar asked Mar 27 '11 01:03

yalis


People also ask

How do you do sequence functions?

The SEQUENCE function allows you to generate a list of sequential numbers in an array, such as 1, 2, 3, 4. In the following example, we created an array that's 4 rows tall by 5 columns wide with =SEQUENCE(4,5). Note: This function is currently available to Microsoft 365 subscribers in Current Channel.

Can Excel generate sequential numbers?

The SEQUENCE function in Excel is used to generate an array of sequential numbers such as 1, 2, 3, etc. It is a new dynamic array function introduced in Microsoft Excel 365. The result is a dynamic array that spills into the specified number of rows and columns automatically.


2 Answers

You can always define functions anonymously, inline:

(map (fn [f x] (f x)) [inc dec] '(98 8))

or shorter, using the #() reader macro:

(map #(%1 %2) [inc dec] '(98 8))

It's a fairly awkward use case though, so I doubt you can reduce it to something shorter using just core clojure or clojure.contrib, but you can easily write your own abstraction:

(defn mapfs [fs coll] (map #(%1 %2) fs coll))
(mapfs [inc dec] [98 8])
> (99 7)
like image 187
Joost Diepenmaat Avatar answered Oct 02 '22 16:10

Joost Diepenmaat


If you're willing to slightly modify the format of your values, things get a bit simpler:

user=> (map apply [inc dec] [[98] [8]])
(99 7)

It's necessary because apply must have a seq as its last argument. This transformation ([98 8] => [[98] [8]]) feels like a reasonable thing to do anyway, since otherwise you depend on the fact that the functions may only take one value apiece. It's of course trivial to do:

user=> (map list [98 8])
((98) (8))

Otherwise, Joost's mapping function #(%1 %2) is as concise as you're going to get.

like image 20
trptcolin Avatar answered Oct 02 '22 14:10

trptcolin