[Haskell-beginners] length problem

Roelof Wobben r.wobben at home.nl
Fri Feb 6 20:52:21 UTC 2015


Alex Hammel schreef op 6-2-2015 om 20:41:
> 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
>

oke, Can you also explain what this function does exactly.

I see a variable n and f and I see cycle en replicate and  a n-1

What is I want to multiply the second item by 2.
That was the challenge I had now.

Roelof



More information about the Beginners mailing list