[Haskell-cafe] zip, map and zipWith for arrays

Henning Thielemann lemming at henning-thielemann.de
Sun Sep 9 07:02:39 EDT 2007


On Sun, 9 Sep 2007, Axel Gerstenberger wrote:

> I am used to work with map, zip and zipWith, when working with lists, 
> however, I could not find such functions for Arrays.

Since 'Array' is an instance of Functor you can use 'fmap' for applying a 
function to all elements.

> For example, in my Finite Element prototype, I have a function
>
>> type Dof = Double
>> type TimeInc = Double
>
>> predictU :: Double -> TimeInc -> Dof -> Dof -> Dof -> Dof
>> predictU beta dt u u_t u_tt = u + dt*u_t + ((dt**2.0)/2.0)*(1.0 - 2.0*beta 
> ) * u_tt
>
> Given 3 equal sized lists un, vn and an of double values [Dof], I apply it 
> with
>
>> u_est = zipWith3 (predictU beta dt) un vn an
>
> I like it's conciseness, but is that efficient?

The problem with combining array is, that they can not only differ in 
length, but can also have different start indices. How to handle this 
generically?

The best way to express that two vectors have the same interval of indices 
is to put them in one array, e.g.

Array i (a, b)    instead of   (Array i a, Array i b)

Of course this is not alway possible.


> The lists can be very long and correspond to a plain C++ vectors in 
> corresponding C++ codes.

Lists can still be the better structure for your application if you do not 
need random access.

> my own "map" for a vector I defined based on the Array documention 
> (Data.Array) as
>
>> mapVec f vec = vec//[ (i, f(vec!i))  |i<-[a..b]]
>>     where
>>         (a,b) = bounds vec

You do not need update (//) if you overwrite all elements. (//) generates 
a new array anyway.

Btw. you can obtain all indices of an array by
   range (bounds vec)


More information about the Haskell-Cafe mailing list