Content deleted Content added
Use the license for your own material. Tags: Reverted Mobile edit Mobile web edit |
m →Language comparison: {{code}} |
||
(5 intermediate revisions by 5 users not shown) | |||
Line 1:
<references group="pakistni" />
{{Short description|Computer programming function}}
{{for|the abstract data type of the same name|Map (data structure)}}
Line 7 ⟶ 8:
The concept of a map is not limited to lists: it works for sequential [[Container (abstract data type)|containers]], tree-like containers, or even abstract containers such as [[futures and promises]].
== Examples: mapping a list ==
Suppose
<syntaxhighlight lang="haskell">
Line 15 ⟶ 16:
</syntaxhighlight>
▲Afterwards we may call
<syntaxhighlight lang="haskell">
Line 25:
=== Visual example ===
Below,
[[File:Mapping-steps-loillibe-new.gif|alt=applying map function processing steps|none|thumb|480x480px|View of processing steps when applying map function on a list]]
Line 37:
</syntaxhighlight>
== Generalization ==
{{see also|Functor|Category theory}}
In Haskell, the [[polymorphic function]]
The [[type constructor]] of lists <code>[]</code> can be defined as an instance of the <code>Functor</code> type class using the <code>map</code> function from the previous example:
Line 79:
=== Category-theoretic background ===
In [[category theory]], a [[functor]] <math>F : C \rarr D</math> consists of two maps: one that sends each object
Functors can also be objects in categories, with "morphisms" called [[natural transformation]]s. Given two functors <math>F, G : C \rarr D</math>, a natural transformation <math>\eta : F \rarr G</math> consists of a collection of morphisms <math>\eta_A : FA \rarr GA</math>, one for each object
==Optimizations==
Line 90:
lead to the same result; that is, <math>\operatorname{map}(f) \circ \operatorname{map}(g) = \operatorname{map}(f \circ g)</math>. However, the second form is more efficient to compute than the first form, because each <code>map</code> requires rebuilding an entire list from scratch. Therefore, compilers will attempt to transform the first form into the second; this type of optimization is known as ''map fusion'' and is the [[functional programming|functional]] analog of [[loop fusion]].<ref>[http://www.randomhacks.net/articles/2007/02/10/map-fusion-and-haskell-performance "Map fusion: Making Haskell 225% faster"]</ref>
▲, defined in terms of a [[Fold (higher-order function)|fold]] such as <code>foldr</code>, which means one can do a ''map-fold fusion'': <code>foldr f z . map g</code> is equivalent to <code>foldr (f . g) z</code>.
The implementation of map above on singly linked lists is not [[tail recursion|tail-recursive]], so it may build up a lot of frames on the stack when called with a large list. Many languages alternately provide a "reverse map" function, which is equivalent to reversing a mapped list, but is tail-recursive. Here is an implementation which utilizes the [[fold (higher-order function)|fold]]-left function.
Line 158 ⟶ 157:
| <code>std::transform(<wbr/>''begin1'', ''end1'', ''begin2'', ''result'', ''func'')</code>
|
| in header {{mono|<algorithm>}}<br /> ''begin'', ''end'', and ''result'' are iterators<br /> result is written starting at ''result''
|
|- valign="top"
Line 209 ⟶ 208:
| Functions exist for other types (''Seq'' and ''Array'')
| Throws exception
|- valign="top"
| [[Gleam (programming language)|Gleam]]
| <code>list.map(''list'', ''func'')</code><br><code>yielder.map(''yielder'', ''func'')</code>
| <code>list.map2(''list1'', ''list2'', ''func'')</code><br><code>yielder.map2(''yielder1'', ''yielder2'', ''func'')</code>
|
|
| drops the extra elements of the longer list
|- valign="top"
| [[Groovy (programming language)|Groovy]]
|
|
|
|
|
Line 381 ⟶ 387:
|- valign="top"
| [[XPath 3]]<br />[[XQuery]] 3
|
|
|
| In <code>block</code> the context item <code>.</code> holds the current value
|