Parametric polymorphism: Difference between revisions

(add E example)
(→‎{{header|Haskell}}: discuss fmap)
Line 152:
=={{header|Haskell}}==
 
<lang haskell> data Tree a = Empty | Node a (Tree a) (Tree a)
 
mapTree :: (a -> b) -> Tree a -> Tree b
mapTree f Empty = Empty
mapTree f (Node x l r) = Node (f x) (mapTree f l) (mapTree f r)</lang>
 
<blockquote><small>
A digression:
 
Note that for the most usefulness in practical programming, a map operation like this should not be defined with a separate name but rather as <code>fmap</code> in an ''instance'' of the <code>Functor</code> ''type class'':
 
<lang haskell>instance Functor Tree where
fmap f Empty = Empty
fmap f (Node x l r) = Node (f x) (fmap f l) (fmap f r)</lang>
 
<code>fmap</code> can then be used exactly where <code>mapTree</code> can, but doing this also allows the use of <code>Tree</code>s with other components which are parametric over ''any type which is a Functor''. For example, this function will add 1 to any collection of any kind of number:
 
<lang haskell>add1Everywhere :: (Functor f, Num a) => f a -> f a
add1Everywhere nums = fmap (\x -> x + 1) nums</lang>
 
If we have a tree of integers, i.e. <var>f</var> is <code>Tree</code> and <var>a</var> is <code>Integer</code>, then the type of <code>add1Everywhere</code> is <code>Tree Integer -> Tree Integer</code>.
</small></blockquote>
 
=={{header|Java}}==