kvanbere
kvanbere

Reputation: 3352

Haskell simple type issue

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

Answers (2)

Daniel Fischer
Daniel Fischer

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

Jerome
Jerome

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

Related Questions