Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

haskell - processing list of pairs..

  • 23-10-2009 1:49pm
    #1
    Registered Users, Registered Users 2 Posts: 2,236 ✭✭✭


    Hi There,

    I'm having some hassle in Haskell atm. Basically i'm trying to get a list of pairs and sum the first elements of each pair and the second elements of each pair.
    eg. sumPairs [(1,2),(2,3),(4,5),(6,7)]
    => (13,17)

    I am able to sum all of the pairs and return a list of the sums of each pair but thats it.

    When I try this I get all kinds of type errors:
    addPair (a,b) (c,d) = ((a+c),(b,d))
    addPairs (a:b:as) = map addPair a b
    
    In the above code i'm taking the first two pairs from the list as and maping them to addPair. How to I define addPair to take two pairs and return one pair?

    I'm competely lost on this..any help appreciated.

    UPDATE:

    I've just gotten addPair to work on its own with two pairs supplied as arguments. When I try and map that function to a list of pairs i'm getting an error
    Type error in application.:
    Expression: map addPair a b
    Term: map
    Type: (e-> f) -> [e] -> [f]
    Does not match: a->b->c->d

    Here's the code:
    addPair :: (Integer,Integer) -> (Integer,Integer) -> (Integer,Integer)
    addPair (a,b) (c,d) = (a+c,b+d)
    addPairs (a:b:as) = map addPair a b
    

    What does the error mean anyway?

    Thanks..


Comments

  • Registered Users, Registered Users 2 Posts: 1,916 ✭✭✭ronivek


    So the first problem is that you're using map incorrectly; it's giving you the type for map which is (e-> f) -> [e] -> [f].

    This is telling you map expects two arguments; the first a function mapping some e to some f, the second a list of e and the result is a list of f.

    The second problem is that map isn't really what you want in this instance; map is simply mapping the elements of some list of length n to some other list of length n. What you're looking to do is to effectively accumulate the values of some list of length n into a single element.

    I would suggest taking a look at foldr and/or foldl; go here http://www.haskell.org/onlinereport/standard-prelude.html; and do a search for foldl and foldr to have a look at the definitions and see if that gives you any ideas.


  • Registered Users, Registered Users 2 Posts: 2,236 ✭✭✭techguy


    Here's what I got to work.
    addPairs [] = (0,0)
    addPairs ((a,b) :as) =
    	let(x,y) = addPairs as in
    		(a+x,b+y)
    
    

    It's the first time using let,in. Hadn't thought of it before. Thanks for your help.


  • Registered Users, Registered Users 2 Posts: 1,916 ✭✭✭ronivek


    Here's my solution using foldl just for future reference;
    addPairs :: (Num a, Num b) => [(a, b)] -> (a, b)
    addPairs ps = foldl (\(x, y) (acc_x, acc_y) -> (x + acc_x, y + acc_y)) (0, 0) ps
    

    Or in an alternative form;
    addPairs2 :: (Num a, Num b) => [(a, b)] -> (a, b)
    addPairs2 ps = foldl addPairAccum (0, 0) ps
    
    addPairAccum :: (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
    addPairAccum (x, y) (acc_x, acc_y) = (x + acc_x, y + acc_y)
    


Advertisement