Parametric polymorphism: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: discuss fmap)
(Derived a Clean implementation based on the Haskell one)
Line 59: Line 59:
right->replace_all (new_value);
right->replace_all (new_value);
}</lang>
}</lang>

=={{header|Clean}}==

<lang clean>::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 clean>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 clean>add1Everywhere :: (f a) -> (f a) | Functor f & Num 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|D}}==
=={{header|D}}==
D template can parametric by constant.
D template can parametric by constant.
Line 167: Line 193:
fmap f (Node x l r) = Node (f x) (fmap f l) (fmap f r)</lang>
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:
<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
<lang haskell>add1Everywhere :: (Functor f, Num a) => f a -> f a