<div class="gmail_quote">On 17 February 2011 19:13, Javier M Mora <span dir="ltr">&lt;<a href="mailto:jamarier@gmail.com">jamarier@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div id=":1vt">First Step: What I want?<br>
------------------------<br>

<br>
In this problem: I think monads as a DSL (Domain Specific Language)<br>
<br>
main = do<br>
  print $ sumM $ do<br>
    makeList 10        -- create candidates list<br>
    multiples 3        -- choose multiples of 3<br>
    multiples 5        -- choose multiples of 5 (not choosed yet)<br>
<br>
Data under de monad is a pair of lists:<br>
(validValues, CandidatesNonValidYet)</div></blockquote></div><br><div>Although my suggestion is not to use a monad for this problem, assuming this is a learning exercise, a solution using the state monad is as follows.<br clear="all">
<br></div><div>I&#39;ll keep the main function exactly as you wanted.</div><div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">sumM x = sum $ fst $ execState ([],[]) x</font></div>
</div><div><br></div><div>or, point-free:</div><div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">sumM = sum . fst . flip execState ([],[])</font></div></div><div><br></div><div>
Here, sumM executes the given state monad, and we end up with the pair of selected and not-selected elements. Then project the fst component, and sum them up.</div><div><br></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">makeList n = put ([],[1..n])</font></div>
<div><br></div><div>makeList initialises the state.</div><div><br></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">multiples n = chooseIf (\ i -&gt; i `mod` n == 0)</font></div><div><br>multiplies chooses those elements satisfying the given criteria. chooseIf is a helper function I&#39;ve chosen to define. Obviously, you can do just fine without it.</div>
<div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">chooseIf f = do</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    a     &lt;- gets fst</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    (b,c) &lt;- partition f &lt;$&gt; gets snd</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    put (a++b,c)</font></div>
</div><div><br></div><div>chooseIf partitions the list of candidates into 2, b is the list of elements satisfying the condition, c is the elements not satisfying it. (Remark: ++ is O(n))</div><div><br></div><div>And that should be it. If you plug these all together, you&#39;ll get 33 as the answer. That is the sum of [3,6,9,5,10]. I don&#39;t know why you didn&#39;t include 10 in the list of candidates, but if that is very important you can remove it by modifying makeList.</div>
<div><br></div><div>Hope this helps.<br>
</div><div><br></div><div>Ozgur</div>