
On 17 February 2011 19:13, Javier M Mora
First Step: What I want? ------------------------
In this problem: I think monads as a DSL (Domain Specific Language)
main = do print $ sumM $ do makeList 10 -- create candidates list multiples 3 -- choose multiples of 3 multiples 5 -- choose multiples of 5 (not choosed yet)
Data under de monad is a pair of lists: (validValues, CandidatesNonValidYet)
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. I'll keep the main function exactly as you wanted. sumM x = sum $ fst $ execState ([],[]) x or, point-free: sumM = sum . fst . flip execState ([],[]) 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. makeList n = put ([],[1..n]) makeList initialises the state. multiples n = chooseIf (\ i -> i `mod` n == 0) multiplies chooses those elements satisfying the given criteria. chooseIf is a helper function I've chosen to define. Obviously, you can do just fine without it. chooseIf f = do a <- gets fst (b,c) <- partition f <$> gets snd put (a++b,c) 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)) And that should be it. If you plug these all together, you'll get 33 as the answer. That is the sum of [3,6,9,5,10]. I don't know why you didn't include 10 in the list of candidates, but if that is very important you can remove it by modifying makeList. Hope this helps. Ozgur