Reputation: 3352
I'm trying to write a function that will add all the elements of two arrays together and return one array. It inputs a duple of lists.
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y) = mapM_ (\ (a, b) -> a + b) (zip x y)
Upvotes: 1
Views: 138
Reputation: 183878
The function you should have used there is
map :: (a -> b) -> [a] -> [b]
But the better choice would have been
addTogether :: Num t => ([t], [t]) -> [t]
addTogether = uncurry (zipWith (+))
The type of mapM_
is
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
which clearly doesn't serve your intended purpose.
Upvotes: 7
Reputation: 4572
I think you're taking the wrong approach here. You will not obtain a reliable addTogether
function by composing functions you vaguely understand until the compiler stops yelling at you. It is kind of dangerous and this is true with Haskell as well as with C. Either you don't use these functions or you thoroughly read their documentation, examples and ideally their code. That's my opinion.
About addTogether
, there are many different ways to implement it. If you spent an hour trying to use zip
and map
without any satisfying results, then you might try something else. For example, if that's your thing, you can handle it in a recursive way:
addTogether :: Num t => ([t], [t]) -> [t]
addTogether ([],_) = []
addTogether (_,[]) = []
addTogether ((x:xs),(y:ys)) = (x + y):addTogether (xs,ys)
No ambiguities here. You can also try to use list comprehension (you want to produce a list right ?), that may look like this:
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y)
| null x || null y = []
| otherwise = [ a + b | n <- [0..min (length x) (length y) - 1],
let a = x!!n,
let b = y!!n]
(it doesn't handle infinite list, I did it quickly)
@Daniel Fischer solution is very nice, but uncurry
may be a bit disturbing at first. You can see it this way:
addTogether :: Num t => ([t],[t]) -> [t]
addTogether (x, y) = zipWith (+) x y
I hope it will help and sorry about my poor English.
Upvotes: 8