[Haskell-cafe] Mapping over multiple values of a list at once?

Sebastiaan Visser sfvisser at cs.uu.nl
Thu Aug 27 07:49:48 EDT 2009


Or, when the list is infinite, turn it into a some neat but cryptic  
State computation:

avgs = (:) <$> ((\d -> sum d `div` 3) <$> StateT (pure . splitAt 3))  
<*> avgs

test = evalState avgs [1,2..]

--
Sebastiaan Visser

On Aug 27, 2009, at 11:19 AM, Eugene Kirpichov wrote:
> How about this one? Should be pretty efficient.
>
> let mavg n xs = let (sum -> seed,rest) = splitAt n xs in map (%n) .
> scanl (\a (p,n) -> a+n-p) seed $ xs `zip` rest
>
>
> 2009/8/27 Patai Gergely <patai_gergely at fastmail.fm>:
>>> For example, starting from
>>>
>>> [4,3,2,6,7]
>>>
>>> you need to find the averages of
>>>
>>> 4,3,2 and 3,2,6 and 2,6,7
>>>
>>> resulting in
>>>
>>> [3,4,5]
>>>
>>> What is the most elegant way to do that?
>> It's probably less elegant than tails, but very likely more  
>> efficient to
>> keep track of running sums instead of summing the sublists over and  
>> over
>> again.
>>
>> import Data.Ratio
>>
>> nsums n xs = map (% n) $ scanl (+) (sum (take n xs)) $ zipWith (-)  
>> (drop
>> n xs) xs
>>
>> Gergely





More information about the Haskell-Cafe mailing list