开发者

Is there a typical name for a function like 'map' that operates on a list of argument lists instead of multiple lists of arguments?

开发者 https://www.devze.com 2022-12-17 19:31 出处:网络
(I finally posted and accepted an answer to the effect of \"no, there isn\'t, and the question isn\'t actually that general\".)

(I finally posted and accepted an answer to the effect of "no, there isn't, and the question isn't actually that general".)

Consider the Common Lisp function 'mapcar'. It takes a function and some lists as arguments, and calls the function with arguments pulled from the same position in each list.

Do standard libraries typically have a similar function that takes a single list, where each element of the list is a list of arguments for the function? What is a function like that typically called whether "standard" or not? (This isn't meant to be a Lisp question, but it's the only functional language+library I halfway know.)

I guess I'm asking if an operation like (in pseudo-Lisp):

(mapcar (curry #'apply function-to-map) list-of-arg-lists)

already has a name that is common across multiple languages or libraries (in the same way that 'map' and 'reduce' are names for common operations, not just specific libra开发者_JS百科ry functions).

Thanks.


I nominate map-apply or maybe mapply if you want to just use it yourself or in a small group.

(defun map-apply (fn arg-lists)
    (mapcar (lambda (arg-list) (apply fn arg-list))
            arg-lists))

(map-apply #'+ '((1 2) (3 4 5)))
  =>
(3 12)

EDIT Of course yours isn't just pseudo-Lisp if you have curry:

(defun curry (f &rest values)
    (lambda (&rest more-values)
        (apply f (append values more-values))))


Consider the Common Lisp function 'mapcar'. It takes a function and some lists as arguments, and calls the function with arguments pulled from the same position in each list.

Do standard libraries typically have a similar function that takes a single list, where each element of the list is a list of arguments for the function?

Well, Haskell defines a series of zipWithN-functions which have similar effects to mapcar for constant argument counts.

zipWith (\a b -> a + b) [1, 2, 3] [1, 2, 3]                   => [2, 4, 6]
zipWith3 (\a b c -> a + b + c) [1, 2, 3] [1, 2, 3] [4, 5, 6]  => [6, 9, 12]

Generalizing this concept for a list of lists will result in this (naively implemented) function zipWithMany

zipWithMany :: ([a] -> b) -> [[a]] -> [b]
zipWithMany f lists 
    | any null lists = []
    | otherwise      = (f $ map head lists) : zipWithMany f (map tail lists)

Example:

zipWithMany sum [[1, 2, 3], [1, 2, 3], [1, 2]] => [3, 6]


There's not really a typical "functional programming" name for that specific operation. In fact, the way I phrased the question presupposes a language that works like Lisp, where functions are applied to lists of arguments. It also assumes that "mapping" in the first place means doing something like Lisp's 'mapcar'.

Not every language works that way. For example, Haskell functions take only one typed argument (see the other answers and comments, and http://www.haskell.org/tutorial/index.html). Mapping a function that takes a tuple type over a list of that type is conceptually similar to the operation I was asking about, and in that case the relevant function is...'map'.

As far as Lisp is concerned, that's just the way the 'mapcar' version of mapping a function over arguments works - it zips up the lists it takes as inputs and applies the function to map to the resulting argument lists. Some other function could just as easily take the zipped argument lists instead and still be called some variant of "map".

My thanks to everyone who contributed to what was, for me, pretty educational.

0

精彩评论

暂无评论...
验证码 换一张
取 消