Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The word "functor" comes from category theory, which is a very general, very abstract branch of mathematics. It has been borrowed by designers of functional languages in at least two different ways.</p> <ul> <li><p>In the ML family of languages, a functor is a module that takes one or more other modules as a parameter. It's considered an advanced feature, and most beginning programmers have difficulty with it.</p> <p>As an example of implementation and practical use, you could define your favorite form of balanced binary search tree once and for all as a functor, and it would take as a parameter a module that provides:</p> <ul> <li><p>The type of key to be used in the binary tree</p></li> <li><p>A total-ordering function on keys</p></li> </ul> <p>Once you've done this, you can use the same balanced binary tree implementation forever. (The type of value stored in the tree is usually left polymorphic&mdash;the tree doesn't need to look at values other than to copy them around, whereas the tree definitely needs to be able to compare keys, and it gets the comparison function from the functor's parameter.)</p> <p>Another application of ML functors is <a href="http://www-2.cs.cmu.edu/Groups/fox/papers/lfp-signatures.ps" rel="noreferrer">layered network protocols</a>. The link is to a really terrific paper by the CMU Fox group; it shows how to use functors to build more complex protocol layers (like TCP) on type of simpler layers (like IP or even directly over Ethernet). Each layer is implemented as a functor that takes as a parameter the layer below it. The structure of the software actually reflects the way people think about the problem, as opposed to the layers existing only in the mind of the programmer. In 1994 when this work was published, it was a big deal.</p> <p>For a wild example of ML functors in action, you could see the paper <a href="http://www.cs.tufts.edu/~nr/pubs/maniaws-abstract.html" rel="noreferrer">ML Module Mania</a>, which contains a publishable (i.e., scary) example of functors at work. For a brilliant, clear, pellucid explanation of the ML modules system (with comparisons to other kinds of modules), read the first few pages of Xavier Leroy's brilliant 1994 POPL paper <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.3950" rel="noreferrer">Manifest Types, Modules, and Separate Compilation</a>.</p></li> <li><p>In Haskell, and in some related pure functional language, <code>Functor</code> is a <em>type class</em>. A type belongs to a type class (or more technically, the type "is an instance of" the type class) when the type provides certain operations with certain expected behavior. A type <code>T</code> can belong to class <code>Functor</code> if it has certain collection-like behavior:</p> <ul> <li><p>The type <code>T</code> is parameterized over another type, which you should think of as the element type of the collection. The type of the full collection is then something like <code>T Int</code>, <code>T String</code>, <code>T Bool</code>, if you are containing integers, strings, or Booleans respectively. If the element type is unknown, it is written as a <em>type parameter</em> <code>a</code>, as in <code>T a</code>.</p> <p>Examples include lists (zero or more elements of type <code>a</code>), the <code>Maybe</code> type (zero or one elements of type <code>a</code>), sets of elements of type <code>a</code>, arrays of elements of type <code>a</code>, all kinds of search trees containing values of type <code>a</code>, and lots of others you can think of.</p></li> <li><p>The other property that <code>T</code> has to satisfy is that if you have a function of type <code>a -&gt; b</code> (a function on elements), then you have to be able to take that function and product a related function on collections. You do this with the operator <code>fmap</code>, which is shared by every type in the <code>Functor</code> type class. The operator is actually overloaded, so if you have a function <code>even</code> with type <code>Int -&gt; Bool</code>, then</p> <pre><code>fmap even </code></pre> <p>is an overloaded function that can do many wonderful things:</p> <ul> <li><p>Convert a list of integers to a list of Booleans</p></li> <li><p>Convert a tree of integers to a tree of Booleans</p></li> <li><p>Convert <code>Nothing</code> to <code>Nothing</code> and <code>Just 7</code> to <code>Just False</code></p></li> </ul> <p>In Haskell, this property is expressed by giving the type of <code>fmap</code>:</p> <pre><code>fmap :: (Functor t) =&gt; (a -&gt; b) -&gt; t a -&gt; t b </code></pre> <p>where we now have a small <code>t</code>, which means "any type in the <code>Functor</code> class."</p></li> </ul> <p>To make a long story short, in Haskell <strong>a functor is a kind of collection for which if you are given a function on elements, <code>fmap</code> will give you back a function on collections</strong>. As you can imagine, this is an idea that can be widely reused, which is why it is blessed as part of Haskell's standard library.</p></li> </ul> <p>As usual, people continue to invent new, useful abstractions, and you may want to look into <em>applicative</em> functors, for which the best reference may be a paper called <a href="http://strictlypositive.org/IdiomLite.pdf" rel="noreferrer">Applicative Programming with Effects</a> by Conor McBride and Ross Paterson.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload