Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The point is that <code>map</code> and <code>f</code> (<code>check</code> in your example) only communicate regarding how to transform individual elements. They don't communicate about how far down the list to transform elements: <code>map</code> always carries on all the way to the end.</p> <pre><code>map :: (a -&gt; b) -&gt; [a] -&gt; [b] map _ [] = [] map f (x:xs) = f x : map f xs </code></pre> <p>Let's write a new version of <code>map</code> --- I'll call it <code>mapOnce</code> because I can't think of a better name.</p> <pre><code>mapOnce :: (a -&gt; Maybe a) -&gt; [a] -&gt; [a] </code></pre> <p>There are two things to note about this type signature:</p> <ol> <li><p>Because we may stop applying <code>f</code> part-way down the list, the input list and the output list must have the same type. (With <code>map</code>, because the entire list will always be mapped, the type can change.)</p></li> <li><p>The type of <code>f</code> hasn't changed to <code>a -&gt; a</code>, but to <code>a -&gt; Maybe a</code>.</p> <ul> <li><code>Nothing</code> will mean "leave this element unchanged, continue down the list"</li> <li><code>Just y</code> will mean "change this element, and leave the remaining elements unaltered"</li> </ul></li> </ol> <p>So:</p> <pre><code>mapOnce _ [] = [] mapOnce f (x:xs) = case f x of Nothing -&gt; x : mapOnce f xs Just y -&gt; y : xs </code></pre> <p>Your example is now:</p> <pre><code>replaceX :: [Int] -&gt; Int -&gt; Int -&gt; [Int] replaceX items old new = mapOnce check items where check item | item == old = Just new | otherwise = Nothing </code></pre>
 

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