This is mostly for my own recreation, feel free to ignore it.

Your solution is fine, but it lacks modularity. What if you discover that you don't actually want to double every other number but triple it? Or if the list of numbers is suddenly a list of words and you need to capitalize every other one? You don't want to have to write a new function from scratch. Let's make a function that applies any function to every other value:

everyOther :: (a -> a) -> [a] -> [a]
everyOther _ []       = []
everyOther _ [x]      = [x]
everyOther f (x:y:xs) = x : f y : everyOther f xs

doubleEveryOther :: [Int] -> [Int]
doubleEveryOther = everyOther (*2)

But hang on, what if the requirements change again and now we have to double every third value? Writing something like this is no fun:

everyThird :: (a -> a) -> [a] -> [a]
everyThird _ []         = []
everyThird _ [x]        = [x]
everyThird _ [x,y]      = [x,y]
everyThird f (x:y:z:xs) = x : y : f z : everyThird f xs

And the implementation of everyHundredAndFifth will obviously be ridiculous. Clearly what we need is an `everyNth` function which allows the programmer to specify which list elements the function is applied to.

One trick is to create a list of functions and use zipWith ($). ($) is just function application; so a list with `id` at every position except the nth will work:

λ zipWith ($) [id, (+1), id, (+1)] [1, 2, 3, 4]
[1,3,3,5]

We can use `cycle` to make an infinite list of functions and `replicate` to generate the padding of the function list:

everyNth :: Int -> (a -> a) -> [a] -> [a]
everyNth n f = zipWith ($) fs
  where
      fs = cycle $ replicate (n-1) id ++ [f] -- e.g. cycle [id, f] when n is 2

everyOther' :: (a -> a) -> [a] -> [a]
everyOther' = everyNth 2

everyThird' :: (a -> a) -> [a] -> [a]
everyThird' = everyNth 3

As for testing whether the length is odd or even: why not just reverse it, double every other number, and reverse it again?

doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther = reverse . everyOther (*2) . reverse

Cheers,
Alex


On Fri, Feb 6, 2015 at 8:55 AM, Roelof Wobben <r.wobben@home.nl> wrote:
Oke,

I have solved it already.
The problem was that I did list.length but Haskell uses length list

Still too much Ruby in my system :(

Roelof



Francesco Ariis schreef op 6-2-2015 om 17:50:
(off-list) please consider not using html in your mails, it's quite difficult
to read them for us who plaintext-friendly client

On Fri, Feb 06, 2015 at 05:47:24PM +0100, Roelof Wobben wrote:
<html>
   <head>

     <meta http-equiv="content-type" content="text/html; charset=windows-1252">
   </head>
   <body bgcolor="#FFFFFF" text="#000000">
     Hello, <br>
     <br>
     I have to double every second element from the right. <br>
     <br>
     So for a even length array that means : 1 , 3 , 5 and so on <br>
     and for a non even lenght that means the 2,4 and so on. <br>
     <br>
     So I thought I could solve that on this way : <br>
     <br>
     -- | Doubles every second number from the right.<br>
     doubleEveryOther :: [Integer] -&gt; [Integer]<br>
     doubleEveryOther []         = []     <br>
     doubleEveryOther (x:[])     = [x]   <br>
     doubleEveryOther (x:(y:zs)) <br>
        | ((x:(y:zs)).length) `mod` 2 /= 0 = [x] ++ (y * 2) :
     doubleEveryOther zs<br>
        | otherwise = [x *2]  ++ y : doubleEveryOther zs<br>
     <br>
     <br>
     <br>
     but this does not work because I see this error message : <br>
     <br>
     <div class="ide-error-span">src/Main.hs@14:8-14:16 </div>
     <div class="ide-error-msg"><span>Couldn't match expected type ‘Int
         -&gt; c0’ with actual type </span>
       <div class="CodeMirror cm-s-default" style="font-size: 14px;">[<span
           class="cm-variable-2">Integer</span>]</div>
       <span title="Click to show/hide extra information"
         class="ide-error-collapse-btn"> …</span><span style="display:
         inline;">
         In the first argument of ‘(.)’, namely ‘(x : (y : zs))’
         In the first argument of ‘mod’, namely ‘((x : (y : zs)) .
         length)’
         In the first argument of ‘(/=)’, namely ‘((x : (y : zs)) .
         length) `mod` 2’<br>
         <br>
         <br>
         Can anyone give me a better way to check if I have a even or odd
         length array ?<br>
         <br>
         Roelof<br>
         <br>
       </span></div>
     <br>
   </body>
</html>
_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners