user668074
user668074

Reputation: 1131

Is there a zipWith function for arrays?

I have two arrays of equal size and I want to combine them element-wise. What is the best way to do this? The array package doesn't seem to provide a zipWith equivalent function.

I'm reluctant to make my own function because the main way I can think of doing this is to convert back and forth with lists. I care about speed and I assume this way is not the most efficient way.

Upvotes: 3

Views: 653

Answers (2)

user8174234
user8174234

Reputation:

Option 1: use repa. Might get some performance benefit from the parallelism as well, should you care about it.

Option 2: just get indices using bounds. I would suggest avoiding list comprehensions in general; though the other answer uses them correctly in this case, it may be worthwhile to get in the habit of doing the right thing.

zipWithArr f xs ys = listArray (bounds xs) $ fmap (liftA2 f (xs !) (ys !)) (range (bounds xs))

The reason that this works is that Haskell's lists are lazy, and we can generally treat them as control structures (due to various optimizations), though we can not treat them as containers. Moreover, GHC evaluates an expression at most once per lambda, so in general you do not need to worry that this will be done inefficiently.

Upvotes: 2

Daniel Wagner
Daniel Wagner

Reputation: 152707

It's pretty easy to cook one up yourself:

zipWithA f xs ys = listArray (bounds xs) [f (xs ! i) (ys ! i) | i <- range (bounds xs)]

Upvotes: 2

Related Questions